Archived

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

fallenang3l

Enginuity's memory manager

Recommended Posts

I have an idea how to improve this class but I don''t know if it''s safe. Basically, I''d like to reuse the memory from dead objects pool, even if the new object to be placed in the old slot is smaller than the original. To put it simply, is it safe to do something like this: void* old = ::operator new(16); // something is a class that takes up 8 bytes something* new = new (old) something; // ... // clean up delete old; Is this gonna work even if class something has has stuff like virtual functions in addition to data members and regular functions? What happens if something constructor throws an exception?

Share this post


Link to post
Share on other sites
From my understanding the IMMObject approach is flawed because it will ultimately delete items which are static, which != good.

By static I mean they are not located in the heap. I know static means something totally different in C++ code, but well its the opposite of dynamic

[edited by - 31337 on July 26, 2003 9:54:22 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by 31337
From my understanding the IMMObject approach is flawed because it will ultimately delete items which are static, which != good.

By static I mean they are not located in the heap. I know static means something totally different in C++ code, but well its the opposite of dynamic

[edited by - 31337 on July 26, 2003 9:54:22 PM]


I fixed that issue by overloading the new operator.

Share this post


Link to post
Share on other sites
quote:
Original post by 31337
From my understanding the IMMObject approach is flawed because it will ultimately delete items which are static, which != good.

By static I mean they are not located in the heap. I know static means something totally different in C++ code, but well its the opposite of dynamic

[edited by - 31337 on July 26, 2003 9:54:22 PM]


You are incorrect.

Share this post


Link to post
Share on other sites
quote:
Original post by 31337
From my understanding the IMMObject approach is flawed because it will ultimately delete items which are static, which != good.

By static I mean they are not located in the heap. I know static means something totally different in C++ code, but well its the opposite of dynamic

[edited by - 31337 on July 26, 2003 9:54:22 PM]


Superpig points that out in his article when he introduces the memory manager. He''s also commented that he''s since gone back and fixed this, I believe by overloading new and delete; the new version will be included in the next article.

As for the original post, I don''t think that''s entirely safe--what if the new object is larger than the old one? Sooner or later, you''ll forget to check, and then you''ve got one object clobbering another. Of course, the dead objects pool is cleared out each frame, so I''m not really sure I see the need for re-using the space before that...?

-Odd the Hermit

Share this post


Link to post
Share on other sites
quote:
Original post by Odd the Hermit
quote:
Original post by 31337
From my understanding the IMMObject approach is flawed because it will ultimately delete items which are static, which != good.

By static I mean they are not located in the heap. I know static means something totally different in C++ code, but well its the opposite of dynamic

[edited by - 31337 on July 26, 2003 9:54:22 PM]


Superpig points that out in his article when he introduces the memory manager. He''s also commented that he''s since gone back and fixed this, I believe by overloading new and delete; the new version will be included in the next article.

As for the original post, I don''t think that''s entirely safe--what if the new object is larger than the old one? Sooner or later, you''ll forget to check, and then you''ve got one object clobbering another. Of course, the dead objects pool is cleared out each frame, so I''m not really sure I see the need for re-using the space before that...?

-Odd the Hermit


I won''t forget to check because the dead objects list is gonna be a multimap, with the key being the available space in bytes. Then I''ll just look through the map with lower_bound(whatever_size_i_want). The only thing I''m worried about is placing a small object where a big object (buffer, etc) once was. I figure I could somehow subdivide this space, placing the new object in whatever space it needs and passing of the rest as vacant space so next objects can be placed in that.

Share this post


Link to post
Share on other sites
I would like to point out that no, I am not incorrect. The version shown in the article will *NOT* work correctly. I would also like to point out that overloading the new operator will not fix the problem because the error in the approach occurs during the deletion of the object.

Even if you overloaded the delete operator so that it wouldn''t delete the object if it was not allocated in the heap, I don''t see any magical way for it to tell. And if its not located in the heap, than what is the freakin point of puting it in the objects list anyways?

While I am not the most knolwedgable C++ programmer, I can tell you that the IMMObject approach has flaws.

You said that superpig mentioned this problem in his article. While he does make a disclaimer saying that we don''t need to keep track of all memory, just memory allocated in the heap, his coding does not reflect that.

However, I really like his style and his approaches. I am greatly considering implementing similar memory management strategies for my new engine. I hope this helps.

Share this post


Link to post
Share on other sites
quote:
Original post by 31337
I would like to point out that no, I am not incorrect. The version shown in the article will *NOT* work correctly. I would also like to point out that overloading the new operator will not fix the problem because the error in the approach occurs during the deletion of the object.

Even if you overloaded the delete operator so that it wouldn't delete the object if it was not allocated in the heap, I don't see any magical way for it to tell. And if its not located in the heap, than what is the freakin point of puting it in the objects list anyways?

While I am not the most knolwedgable C++ programmer, I can tell you that the IMMObject approach has flaws.

You said that superpig mentioned this problem in his article. While he does make a disclaimer saying that we don't need to keep track of all memory, just memory allocated in the heap, his coding does not reflect that.

However, I really like his style and his approaches. I am greatly considering implementing similar memory management strategies for my new engine. I hope this helps.


Listen, you are wrong man. The delete operator will NEVER be called on an IMMObject allocated on the stack because collectgarbage function cycles through the dead objects list deleting only those elements which are on the list. How are objects placed on that list? When you create an MMPointer to an IMMObject, reference count is upped by one and this pointer is put on the live objects list. When reference count drops to 0, this pointer is removed from live objects list and put on dead objects list, where delete will be called on it sometime later. This will never happen for an auto object (correct behavior) because it's this pointer will NEVER be placed on live objects list (this is done in overloaded new), hence can never be placed in dead objects, therefore can never be called delete upon.
I'm tired of your ranting man, either learn C++ or stop criticizing valid code.


[edited by - fallenang3l on July 27, 2003 5:45:12 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
31337, before you start sounding like a cretan, I think you should look more into these topics: temporary object, local-stack-frame objects, and the C/C++ keyword auto, which is implicit on the formers. BTW, you sound like you are FOS, because you''re arguing with 25+ year-old gurus in the industry. I''m not one, but at least I know how to thoroughly read/understand the thread attached to the articles meaningfully named "discuss this article." In those debugging discussions, all of this BS was covered by people of various skill levels including myself. Stop trying to take other peoples credit by acting like you know what you''re talking about when you are blatantly just re-inventing the well-documented "wheel." No hard feelings buddy!

Share this post


Link to post
Share on other sites
I have read most of the "Discuss this article" thread and correct me if I'm wrong but there is a redone IMMObject class.

fallenangel - Here is my arguement, clearly logical. The constructor for the IMMObject class is this:

IMMObject::IMMObject()
{
liveObjects.push_back(this);

//update the constructor to initialise refCount to zero
refCount=0;
}

So *automatically* the item is placed on the list of "live" objects. Are you following me thus far?

Now naturally the item has refCount set to 0, meaning that the next time we clean out the garbage, this function is going to put it in its dead list when Release is called:

void IMMObject::Release()
{
--refCount;
if(refCount<=0)
{
liveObjects.remove(this);
deadObjects.push_back(this);
}
}

Are you with me? So right now, after our Release() function is called, or object is placed on the dead objects list. Now, it is only a matter of time before this function gets called, THUS DELETING the object regardless if its located on the stack. Look here:

void IMMObject::CollectGarbage()
{
for(std::list::iterator it=deadObjects.begin(); it!=deadObjects.end(); it++)
{
delete (*it);
}
deadObjects.clear();
}

Even if for some reason the stack located object is not ever placed on the dead objects list (which would make sense because who in their right mind is going to call Release() on a stack located object?), it will *still* get deleted when this function is called:

void IMMObject::CollectRemainingObjects(bool bEmitWarnings)
{
CollectGarbage();
for(std::list::iterator it=liveObjects.begin();it!=liveObjects.end();it++)
{
IMMObject *o=(*it);
if(bEmitWarnings)
{
//log some kind of error message here
//we'll be covering how to log messages later this article
}
delete o;
}
liveObjects.clear();
}

Eventually, nomatter what the circumstance of the refcount variable is, if a stack located object which inherits the IMMObject class is used, it will eventually be deleted.

Also, I HAVE TRIED IT. I got the same exact results I am talking about.

Now PLEASE, if I am wrong I desperatly want to find out, PLEASE show me where I am wrong. I think it has to have something to do with this "auto" operator so I am going to look it up. Which specific page/function/line can I look at which will show me how this stops the object from being put on the live objects list, because to me it looks like the constructor puts it there nomatter what.

[edited by - 31337 on July 27, 2003 12:32:28 AM]

Share this post


Link to post
Share on other sites