3

Is there a way to get size of a single element or element count allocated using operator new[] ?

What I mean:

void* Object::operator new[](size_t size)
{
    void *temp = ::operator new(size);

    //Get size of single element or count of elements being allocated

    return temp;
}

Why I need it:

operator new(size_t) and operator new[](size_t) are invoked only when object is allocated on heap so I've got an idea of creating c++ garbage collection based on this.

  1. All objects inherit from Object class
  2. Object class overrides operator new(size_t) and operator new[](size_t)like this:

    void* Object::operator new(size_t size)
    {
        Object& result = *static_cast<Object*>(::operator new(size));
        result.referenceCount = (int)&result;
        return &result;
    }
    
  3. Constructor of Object uses this information:

    Object::Object()
    {
        if ((void*)referenceCount != this)
        {
            referenceCount = -1; //stack object no reference counting
        }
        else
        {
            referenceCount = 1; //heap object count references
        }
    }
    
  4. Garbage Collector user referenceCount field to work with.

What I need now is to implement operator new[](size_t) to set referenceCount and that is why I need size of single element or element count. Impelenting operator new[](size_t) for every object out of the question.

Any ideas?

EOG
  • 1,677
  • 2
  • 22
  • 36
  • 1
    Reference counting isn't a GC. Use shared pointers for that, and do so selectively, not without good reason. And even apart from that, your idea is very hacky at best. –  Dec 28 '12 at 20:02
  • 1
    1) This code is broken on 64-bit platforms, `int` cannot portably store a pointer value. 2) An object created on the stack will have an uninitialized `referenceCount` member, so you can't safely access it in the constructor. – Jonathan Wakely Dec 28 '12 at 20:46
  • @Jonathan Wakely 1)int and pointer on 64bit program has 64bit size, int and pointer on 32bit program has 32bit size! 2) referenceCount is not initialized but by setting it in operator new I can asume that it will have proper value (it's hacky as delan commented) – EOG Dec 28 '12 at 21:09
  • 1
    1) no, `int` on 64-bit platforms is 32-bit, look it up. 2) no, for a stack object nothing initializes the member, so it could even have the same value as `this` by pure chance. – Jonathan Wakely Dec 28 '12 at 21:20
  • 1) I wrote a quick test and you were right. This artucule http://en.wikipedia.org/wiki/64-bit_computing fooled me (first sentence). 2) read in to my code – EOG Dec 28 '12 at 21:30
  • I read the code, when you don't use `operator new` nothing sets the member, so it contains junk! I understand what the code does better than you do. It would also fail if someone created one of your objects using a zeroing allocator that zeros out the memory before constructing objects. It would also be very fragile if you use multiple inheritance. In summary: it doesn't work, give up. – Jonathan Wakely Dec 28 '12 at 21:42

1 Answers1

3

This seems very Java-esque to me. Would it be simpler to simply write your program in Java? Anyone who has to maintain your C++ code in the future will appreciate it if you use idiomatic C++ to start with. For example use smart pointers to manage your memory rather than trying to implement garbage collection based on everything inheriting from Object.

I should point out that you left out "multiple inheritance is prohibited" from your list of conditions because in the presence of multiple inheritance your cast of raw, uninitialized memory to an Object* may not do the pointer adjustments it needs to to access the correct address of referenceCount.

Additionally if the memory of referenceCount happens to hold the address of a stack-based Object at construction your code will believe it to be heap-allocated and eventually result in UB when you delete a stack pointer.

But after all that if you still really really really want to do this, I think your only option is to use CRTP to automatically inject the array new operator into each child class. At least that way you don't have to write it yourself for every child.

Mark B
  • 95,107
  • 10
  • 109
  • 188