This topic is now archived and is closed to further replies.


Chaning object's data before constructor and reading them after destructor

Recommended Posts

I''m trying to write some garbage-collector (simillar to the one in enginuity). I''ve got some variables to hold object''s size, its reference count and iterator to the object in living (dead) objects list (std::list). In operator new, I first allocate the memory and then I reinterpret_cast it to Gc *. Add the object to list and set the var''s. In delete, I also reinterpret the pointer to Gc * and read the iterator, then I remove the object from the list using the iterator. It all works fine, till I try to use it with MI (I want one class to be garbage-collected, but I don''t want its parent to be so). The problem is in the operator delete. When I try to read the iterator to the object, it''s zeroed. I don''t know why, I don''t know how, but it happened. In no of the destructors I''m accessing it (because it''s private). But then I can''t remove the object from the objects list. Weird is that when I don''t have MI it doesn''t occur... Code is here:
typedef long addr;

#define GC Gc (sizeof (*this), (addr)this)

class Gc {
	Gc (size_t size, addr self);
	Gc (const Gc &gc);
	virtual ~Gc () = 0;
	void *operator new (size_t size);
	void operator delete (void *mem);
	static void gc ();
	static void cleanup ();
	void addRef ();
	void removeRef ();
	static inline unsigned bytesAllocated ();
	static inline unsigned bytesGarbage ();
	static inline unsigned objectsAllocated ();
	static inline unsigned objectsGarbage ();
	int ref;
	size_t objSize;
	bool stack;
	std::list <Gc *>::iterator self;
	bool gar; //is object garbage?

#ifdef DBG
	static unsigned allocations;
	static unsigned deallocations;
	static unsigned allocated;
	static unsigned sizeGarbage;
	static unsigned numObjects;
	static unsigned numGarbage;
	static std::list <Gc *> objects;
	static std::list <Gc *> garbage;

unsigned Gc::bytesAllocated ()	{ return allocated; }
unsigned Gc::bytesGarbage ()	{ return sizeGarbage;}
unsigned Gc::objectsAllocated (){ return numObjects;}
unsigned Gc::objectsGarbage ()	{ return numGarbage;}

///--- CPP FILE ---///

Gc::Gc (size_t size, addr a)
  : ref (0),
    gar (true)
	Gc *o = reinterpret_cast <Gc *>(a);
	std::list <Gc *>::iterator me =	std::find (garbage.begin (), garbage.end (), o);

	objSize = size;

	if (me == garbage.end ())
		stack = true;
	else {
		stack = false;
		self = me;

Gc::Gc (const Gc &gc)
	garbage.push_back (this);
	self = garbage.end ();	//nastavim pointr na sebe sama

	ref = 0;				//je to vodpad

	gar = true;
	objSize = gc.objSize;
	stack = gc.stack;		

Gc::~Gc ()

void *Gc::operator new (size_t size)
	//nejdriv alokuju pamet

	void *mem = malloc (size);

	if (mem == 0)
		throw std::bad_alloc ();

	Gc *object = reinterpret_cast <Gc *>(mem);

	//zvysim pocitadlo alokovani

	sizeGarbage+= size;

	//pridam objekt do seznamu objektu

	garbage.push_back (object);

#ifdef DBG

	//vratim pamet

	return mem;

void Gc::operator delete (void *mem)
	if (mem == 0) return;
	Gc *object = reinterpret_cast <Gc *>(mem);
	//zjistim si velikost objektu

	int size = object->objSize;

	//smazu objekt ze seznamu

	if (object->gar) {
		garbage.erase (object->self);

		//snizim pocitadlo odpadku

		sizeGarbage-= size;
	} else {
		objects.erase (object->self);

		//snizim pocitadlo objektu

		allocated-= size;

#ifdef DBG

	//smazu objekt

	if (!object->stack)
		free (mem);

void Gc::addRef ()

	if (!stack && ref <= 1) {
		//objekt vstal z mrtvejch

		//odstranim ho ze seznamu odpadku

		garbage.erase (self);

		//pridam ho na seznam objektu

		objects.push_back (this);
		self = objects.end ();			//nastavim pointr na sebe sama


		gar = false;

		//snizim pocitadlo odpadku

		sizeGarbage-= objSize;

		//zvysim pocitadlo objektu

		allocated+= objSize;

void Gc::removeRef ()

	if (!stack && ref <= 0) {
		//posledni reference k tomuhle vobjektu -> udelam z nej vodpad

		//smazu ho ze seznamu objektu

		objects.erase (self);

		//pridam ho k odpadkum

		garbage.push_back (this);
		self = garbage.end ();			//nastavim pointr na sebe sama

		gar = true;

		//snizim pocitadlo objektu

		allocated-= objSize;

		//zvysim pocitadlo odpadku

		sizeGarbage+= objSize;

void Gc::gc ()
	//projedu celej seznam odpadku a vsechny je jeden po druhym vymazu

	std::list <Gc *>::iterator i = garbage.begin ();

	trace ("Gc::gc", garbage.size ());

	while (i != garbage.end ()) {
		std::list <Gc *>::iterator temp = i;
		delete *temp;

	//vymazu seznam odpadku

	garbage.clear ();

void Gc::cleanup ()
	//uvolnim neplatny objekty

	gc ();

	//uvolnim i ty platny objekty

	std::list <Gc *>::iterator it = objects.begin ();

	while (it != objects.end ()) {
		std::list <Gc *>::iterator temp = it;

		delete *temp;

	objects.clear ();

And this is how it''s derived:

template <typename T>
class DynMemArray : public Array <T>, public Gc {
	DynMemArray () : Array <T> (), GC
	{ }

	DynMemArray (size_t size) : Array <T> (), GC
		alloc (size);

	DynMemArray (const DynMemArray <T> &r) : Array <T> (r), Gc (r)
	{ }

	~DynMemArray ()
		//uvolnim pole

		if (mem) release (); //some internal stuff...



I''m sory for it''s so long and that there''re czech comments . Oxyd --- - Unreadable code is code written on a piece of paper, but not the one, in which the programmer is using a space in the place you don''t. - Real programmers aren''t afraid of goto

Share this post

Link to post
Share on other sites