Ok I wrote that post way too fast and did not clarify myself. So I think I will take another shot at this. My apologies if I just caused more confusion.
Your code:
Obj* o = (Obj*)obj-sizeof(unsigned int);
is roughly equivalent to:
Obj *o = (Obj*)obj; o = &o[-4];
You are backing up 32 bytes. I do not have an answer for why you are seeing any positive results from this, but I do know that you are changing memory you should not be changing. This is the same if you use a vector, list or a simple C array.
That is why I suggested that you cast to char* because that is a single byte array.
Obj* o = (obj*)((char*)obj-sizeof(unsigned int))
The code above does what you are currently trying to do.
Now that I have re-read over this code again I see a few other problems. Your function RemoveInstance takes a pointer and tries to change 4 bytes before it in memory. The first thing is that I see no connection in this code between the address that T* ptr points to and the unsigned int refCount before the T* ptr.
Lets take out all the low level details and try to draw a simple picture here. So we will say that we have a single Obj structure which the deque has allocated for you at address 0x000004.
0 1 2 3 4 5 6 7 8 +-----------------------+-----------------------+0x0004 | unsigned int refCount | T* ptr | +-----------------------+-----------------------+
Ok so now lets say that you allocate with new or malloc some arbitrary 100 bytes of data. You get back a pointer that points to address 0x0244. So you set T* ptr to that address.
1 1 1 1 1 1 1 1 1 1 2 2 2 2... 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3... +----------------------------------------------...0x0244 | Some data filling 100 bytes ... +----------------------------------------------...
So now the T* ptr = 0x0244. That is because you need that pointer to point to the actual memory you are allocating. As you can see here there is a gap between the T* ptr and the address it is pointing to.
So when you call RemoveInstance(o.ptr); What you are doing is RemoveInstance(0x0244); Then your are attempting to back up in memory 4 bytes (although your code backs up 32 so it's even worse) you are changing a value at addres 0x0240. Although undefined I can tell you that at 4 bytes in Win32 debug you are probably writing over fence memory put in place by the crt memory allocation routines but at 32 I can only guess that it's part of the memory header or could end up outside your process's virtual address space. In any case that is bad behavior and you will probably stumble upon some memory that you are not allowed to change and will instead raise an exception.
Now for a solution. Instead of passing in the pointer to RemoveInstance pass in a reference to the object in the deque list.
void Release(){ if (memory.size()) { // iterate through the deque and remove all uninitialized blocks std::deque<Obj>::iterator memoryItor; for (memoryItor = memory.begin(); memoryItor != memory.end(); memoryItor++) { Obj &o = (*memoryItor); // <- Changed RemoveInstance(o); // remove the instance <- Changed } CollectGarbage(); // call the garbage collector numUsed = 0; numFree = 0; }}// remove an instancevoid RemoveInstance(Obj &obj) // <- Changed{ obj->refCount--; numUsed--; numFree++;}
I am making some assumptions here of what you are doing because you have not provided enough code to get a full picture, so I am filling in the gaps, but I am confident that is your problem.