R
Robert Potthast
Hello,
I want to make my garbage collector more safe. To make it more safe I
need to know if an object has been allocated on the stack or on the
heap using the operator new. My garbage collector uses a mixture of
reference counting and smart pointers. I have got a base class
("Object") which handles all the memory management stuff.
I have worked out different approaches to pass the info to my base
class (won't name all):
- Cast the allocated memory chunk to the base object and set directly
the heap-flag. This will most likely fail with virtual and multiple
inheritance. A template operator new (not placement new) would be
great.
- Set upon call of the operator new a static bool flag if there is
currently a not yet constructed (but already allocated) object in the
heap. The Object constructer will then determine wether or not the
object is heap-allocated. This might fail if I have multiple base
classes - the construction order might be wrong, and if other objects
are constructed before, it might happen that other objects will be
marked incorrect.
struct Object
{
Object()
{
if (heapObject)
isHeapAllocated = true; //If another object has been constructed
before, "isHeapAllocated" will be false, even though it should be true.
else
isHeapAllocated = false;
heapObject = false;
/* Do some MM */
}
void* operator new(size_t objectsize)
{
void *newObject = malloc(objectsize);
heapObject = true;
return newObject;
}
/* Many other member functions */
bool isHeapAllocated;
static bool heapObject;
};
- Add the allocated object to a list. When the Object constructor is
called it will search the list for a value equal to "this".
struct Object
{
Object()
{
/* Might not find anything. */
std::list< Object* >::iterator it = std::find(heapObjects.begin(),
heapObjects.end(), this);
if (it != heapObjects.end())
isHeapAllocated = true;
else
isHeapAllocated = false;
}
void* operator new(size_t objectsize)
{
void *newObject = malloc(objectsize);
heapObjects.push_front(static_cast< Object* >(newObject));
return newObject;
}
/* Many other member functions */
bool isHeapAllocated;
static std::list< Object* > heapObjects;
};
The search will fail if the Object base class has not the same address
like the full object - which might be the case with virtual or multiple
inheritance.
- The last possibility would be to wrap the new operator, and instead
use own functions or factories for allocation and construction. I would
need to rewrite a lot of code. And I bet many new issues would arise.
Have you got any ideas? Maybe I can somehow rethink my memory
management.
Thanks in advance,
Robert
I want to make my garbage collector more safe. To make it more safe I
need to know if an object has been allocated on the stack or on the
heap using the operator new. My garbage collector uses a mixture of
reference counting and smart pointers. I have got a base class
("Object") which handles all the memory management stuff.
I have worked out different approaches to pass the info to my base
class (won't name all):
- Cast the allocated memory chunk to the base object and set directly
the heap-flag. This will most likely fail with virtual and multiple
inheritance. A template operator new (not placement new) would be
great.
- Set upon call of the operator new a static bool flag if there is
currently a not yet constructed (but already allocated) object in the
heap. The Object constructer will then determine wether or not the
object is heap-allocated. This might fail if I have multiple base
classes - the construction order might be wrong, and if other objects
are constructed before, it might happen that other objects will be
marked incorrect.
struct Object
{
Object()
{
if (heapObject)
isHeapAllocated = true; //If another object has been constructed
before, "isHeapAllocated" will be false, even though it should be true.
else
isHeapAllocated = false;
heapObject = false;
/* Do some MM */
}
void* operator new(size_t objectsize)
{
void *newObject = malloc(objectsize);
heapObject = true;
return newObject;
}
/* Many other member functions */
bool isHeapAllocated;
static bool heapObject;
};
- Add the allocated object to a list. When the Object constructor is
called it will search the list for a value equal to "this".
struct Object
{
Object()
{
/* Might not find anything. */
std::list< Object* >::iterator it = std::find(heapObjects.begin(),
heapObjects.end(), this);
if (it != heapObjects.end())
isHeapAllocated = true;
else
isHeapAllocated = false;
}
void* operator new(size_t objectsize)
{
void *newObject = malloc(objectsize);
heapObjects.push_front(static_cast< Object* >(newObject));
return newObject;
}
/* Many other member functions */
bool isHeapAllocated;
static std::list< Object* > heapObjects;
};
The search will fail if the Object base class has not the same address
like the full object - which might be the case with virtual or multiple
inheritance.
- The last possibility would be to wrap the new operator, and instead
use own functions or factories for allocation and construction. I would
need to rewrite a lot of code. And I bet many new issues would arise.
Have you got any ideas? Maybe I can somehow rethink my memory
management.
Thanks in advance,
Robert