int main(int, char**) { int* n = new int[42]; return 0; }
1 active allocations totalling 168 bytes: + ID 00000002, tag ID 0x00000000: 0x00356B84 168 bytes [main.cpp:9 (main)] End of allocations
Posted 14 February 2008 - 02:14 AM
int main(int, char**) { int* n = new int[42]; return 0; }
1 active allocations totalling 168 bytes: + ID 00000002, tag ID 0x00000000: 0x00356B84 168 bytes [main.cpp:9 (main)] End of allocations
Posted 14 February 2008 - 02:22 AM
Quote:
It uses a singleton for the memory manager (I know, I'm sorry to all the singleton haters out there), but I belive it's perfectly justified in this case.
Quote:
It uses some #pragma black magic to make sure the memory manager is one of the very first things created,
Posted 14 February 2008 - 02:35 AM
Quote:That's a good point, I'll add that to my TODO list for it.
Original post by Antheus
Fortunately for you, it's not a kosher singleton, since it uses explicit and not lazy construction.
So I guess you're off the hook, and the class is merely a global. Still, at quick glance, you might as well replace the class with namespace, and not lose anything at all.
Quote:Technically, it makes a global in the init_seg section. That global should be the first constructed and the last destructed (If any other globals are in the init_seg the order is undefined). The global creates and destroys the memory manager; the important part is that the memory manager is destroyed after everything else.
Original post by Antheus Quote:This intrigues me. At least I've never heard of such technique, most other memory managers need to be included at beginning.
It uses some #pragma black magic to make sure the memory manager is one of the very first things created,
Posted 14 February 2008 - 03:28 AM
Posted 14 February 2008 - 03:43 AM
Quote:That's the first I've seen of that actually. In what ways is it similar? A lot of memory leak checkers are based on similar principals.
Original post by dmail
I have a very similar memory tracker and is based of C++ for game programmers and it looks like your code is also a derivative of it. I thought that Noel Llopis' code had a license? If not it, it would be nice to just give some credit to the original author.
Posted 18 February 2008 - 02:55 AM
Quote:
Original post by Antheus Quote:
It uses a singleton for the memory manager (I know, I'm sorry to all the singleton haters out there), but I belive it's perfectly justified in this case.
Fortunately for you, it's not a kosher singleton, since it uses explicit and not lazy construction.
So I guess you're off the hook, and the class is merely a global. Still, at quick glance, you might as well replace the class with namespace, and not lose anything at all.
Posted 18 February 2008 - 03:09 AM
Quote:"Kosher" meaning "normal" or "standard" singleton. A normal singleton constructs itself the first time it's referenced, E.g.:
Original post by TechnoCore
What does 'Kosher Singleton' mean, and why is it bad?
/Curious
MemMgr& MemMgr::Get()
{
static MemMgr instance;
return instance;
}
Posted 18 February 2008 - 08:01 AM
Posted 18 February 2008 - 08:09 AM
Quote:Interesting, I didn't know about allocation hooks or __declspec(allocate), I'll have a look at them. I agree that storing 64 bytes (Actually, it's more with the stack trace contexts [rolleyes]) is a bit much for each allocation, but I haven't run into any problems with it (yet).
Original post by Jan Wassenberg
Nice that you release code :)
Some comments, since I am working on the same thing ATM:
- __declspec(allocate) may be preferable to #pragma init_seg in that it avoids C4074
- using an allocation hook instead of overloading new is a bit more robust (what happens if you link against another library that decides to do the same?) and also covers use of malloc/getcwd/strdup etc.
More importantly: we certainly can't hope to reach Valgrind's degree of studliness, so it makes sense to use that on Linux and otherwise consider the MS and Mac platform libraries. The MS debug heap already does all of this and more - except for recording a call stack. Wouldn't it be nifty to reuse that code, just modifying it to also gather a stack trace? This is what the earlier, safer versions of VLD did.
In fact, we can take this approach one step further. Storing 64 bytes of caller information *for each allocation* is a bit hard to justify, especially if there are lots of allocations. (what good is debug mode if you can't run it or it's just too slow?) It turns out that several frames can be stored with *zero* space overhead: we just need to stash them in the memory block header's file and line fields. Those 64 bits (for 32-bit builds) are enough to store at least two full 32-bit pointers* or up to six encoded offsets, the first being relative to the code segment.
* dirty trick: you need one bit to differentiate the pointer vs offset, but get it back by not storing the LSB (since no call instruction can be less than two bytes, rounding the return address down to the next even address does not change the function).
> today MindWipe was having issues with the CRT memory leak code
Out of curiosity, what kind of problems?
Posted 18 February 2008 - 12:15 PM
Posted 18 February 2008 - 06:50 PM
Quote:
This intrigues me. At least I've never heard of such technique, most other memory managers need to be included at beginning.
Quote:
The problem MindWipe was having turned out to be a genuine memory leak (GLUT never returning, so memory never being deleted), but I thought it was because some global was getting destroyed after the _CrtDumpLeakCheck (Or whatever the function is).
Posted 18 February 2008 - 07:21 PM
Posted 18 February 2008 - 09:40 PM
Quote:I've posted a similar memory manager before, but it was just straight from my engine code and needed tweaking to get it to compile; it was intended as a code sample for something or other, not something people can download and drop into their code like this.
Original post by Boder
Because Evil Steve, you haven't mentioned this before?
Posted 18 February 2008 - 11:04 PM
Quote:
Original post by Jan Wassenberg
Zipster: good idea. 28 MB in spite of this optimization, though? That is an excellent motivation for me to finish up the zero storage scheme :)
Posted 19 February 2008 - 03:01 AM
Quote:
Original post by Evil Steve
"Kosher" meaning "normal" or "standard" singleton. A normal singleton constructs itself the first time it's referenced, E.g.:
*** Source Snippet Removed ***Or similarly, with dynamic allocation. In this case, the singleton is created and destroyed explicitly - the key point is that it's not constructed the first time it's used.
Singletons are usually considered a sign of bad design, since they're really just globals in disguise. See Promit's Journal for some relevant links.