Skip to main content
GameDev.net gamedev.net
🔒 Locked

overloading operator new (advanced)

Started by qesbit Apr 3, 2005 at 4:52 PM 16 replies 3.3k views
Original Post
qesbit
qesbit
I am trying to find a way to get some information to operator new without having to break the C++ model. Essentially: I want to be able to pass file name, line number, and other info to new in my memory manager, so when I find leaks I have more info to debug. I have looked at Paul Nettle's code.. borrowed some ideas from it. However, I really don't like the way it does this. Is there any way to do this without breaking C++ model so that I can just use x = new foo; instead of x = new (whatever) foo; I don't like that (whatever) stuff. Thanks
Yohumbus
Yohumbus
Yes, Use a define to replace new with new(whatever) where whatever has the preprocessor words for file name and line number and whatnot (I dont remembor them). Anyway the code will look the same and the define can be removed if you want to switch back to the old model.
ASCII stupid question, get a stupid ANSI
Fruny
Fruny
Quote:
Original post by Yohumbus
Yes, Use a define to replace new with new(whatever) where whatever has the preprocessor words for file name and line number and whatnot (I dont remembor them).


That will break a lot of code, starting with custom operator new declarations and placement new calls. Using the preprocessor to re-define reserved keywords is a Bad Idea™

It would work if you #define NEW instead of new and consistently use NEW in your own code.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Jan Wassenberg
Jan Wassenberg
heh, "(advanced)" always cracks me up ;)

Quote:
That will break a lot of code, starting with custom operator new declarations and placement new calls. Using the preprocessor to re-define reserved keywords is a Bad Idea

Agree in principle, but a decent workaround is to disable/reenable (via #include) the macro hook around any local operator new. That fixes conflicts in your code, and system/external headers are no problem if you maintain the convention that the hook definition comes after those.

IMHO the C++ mem allocation system is rather ugly - it's not orthogonal and uses special syntax to hack around the issue. If you don't like the macro approach (which isn't foolproof for the task at hand), that's it as far as standard C++ is concerned. Fortunately you can use platform-specific tricks (walking the stack, 'introspection' via compiler debug information) to get at the information you want. See the implementation in my memory tracker - it is pretty complicated, though.
E8 17 00 42 CE DC D2 DC E4 EA C4 40 CA DA C2 D8 CC 40 CA D0 E8 40E0 CA CA 96 5B B0 16 50 D7 D4 02 B2 02 86 E2 CD 21 58 48 79 F2 C3
qesbit
qesbit
Quote:
Original post by Jan Wassenberg
heh, "(advanced)" always cracks me up ;)



You have to agree it's more advanced than the normal question "how do I use new?"
:-)

I don't like any of these ideas, I've already done them and I think they suck.
I said advanced in the hopes somebody has a cleaner solution.

[EDIT]
I looked at your library.. you need to concentrate more on better algorithms for real-time performance. My memory manager is fully garbage collected and it is optimized for extreme real-time performance.

I just want a cleaner way to get this info to new than bull**** macro hacks.

Genjix
Genjix
... everyone likes the garbage collection.

which reminds me... why doesn't boost have this sort of thing?
qesbit
qesbit
Quote:
Original post by Rob Loach
Just curious, why do you want to overload the new operator?



If you need to ask that question..

Forget it noobs. I found a better solution.
nilkn
nilkn
Quote:
Original post by Rob Loach
Just curious, why do you want to overload the new operator?


By overloading the global new and delete operators, you can seamlessly integrate the code for your entire project with a memory allocation and deallocation tracker. This way your program will be able to find memory leaks, etc. without you having to type anything extra, or use a custom Alloc() function, which would just be ugly and kill readability.
Sneftel
Sneftel
#defining keywords is illegal, although I've never seen a preprocessor that enforces the restriction.

qesbit, if you're calling Rob Loach a "noob", you obviously have no idea.
Nemesis2k2
Nemesis2k2
Don't bother. He's already found a better solution and doesn't need help from us noobs.
Evil Steve
Evil Steve
Quote:
Original post by qesbit
Forget it noobs. I found a better solution.
What way did you find?
Using macros to redefine the new and delete keywords is the standard way of getting around it (as Paul Nettle's code shows).

However, what I don't understand is how your memory manager is "fully garbage collected and it is optimized for extreme real-time performance", and yet you need to store debug information like the file and line the call was made from, and the fact you do GC. I understand that GC can be useful some times, but I can't see why you'd want to have a highly optimized memory manager doing garbage collection.

EDIT: When I say "the standard way of getting around it", there is no "standard" way, but that's the common way to do it. Unless you want to go for the method you said you didn't want to: x = new (whatever) foo;
qesbit
qesbit
Quote:
Original post by Evil Steve
Quote:
Original post by qesbit
Forget it noobs. I found a better solution.


What way did you find?
Using macros to redefine the new and delete keywords is the standard way of getting around it (as Paul Nettle's code shows).


Standard? haha. Go back to ripping code from open source projects.

Quote:

However, what I don't understand is how your memory manager is "fully garbage collected and it is optimized for extreme real-time performance"


Because C/C++ is a very difficult language to make a garbage collector for and it is exactly the information I need when and if the garbage collector does miss blocks, so I can analyze the code and figure out why it missed it.

It's optimal on Windows systems.

Understand?

[EDIT]
You think knocking me down a 100 points on my rating hurts my feelings? You're all a bunch of noobs anyways, I really don't need your help.

You know, I might have been willing to share it with others, but after being
slammed so hard on my rating, you can pretty much kiss the baby on it.
Evil Steve
Evil Steve
Quote:
Original post by qesbit
Standard? haha. Go back to ripping code from open source projects.
Perhaps you'd like to tell us what method you found? Almost every memory manager I've seen uses macros to get around it (Although yes, they've all been open source. I don't think a closed source memory manager would work on account of you needing the source code to use it).
You could overload the new operator for a class I suppose, but I don't know if that works for derived classes (I've never needed to overload the new operator for a single class)

Quote:
Original post by qesbit
Because C/C++ is a very difficult language to make a garbage collector for and it is exactly the information I need when and if the garbage collector does miss blocks, so I can analyze the code and figure out why it missed it.
Ah, that's true [smile]. I usually write two versions of a memory manager. One for debug mode, which records things like memory leaks, and the file and line numbers for allocations, and another which is optimized, and doesn't record any debug info.

Quote:
Original post by qesbit
It's optimal on Windows systems
So you make use of Windows specific features? Or you've only tested it on windows?

Quote:
Original post by qesbit
Understand?
No, not really. You haven't told us what you came up with, or why it's better or more efficient than any of the methods we've suggested.

Quote:
Original post by qesbit
You think knocking me down a 100 points on my rating hurts my feelings? You're all a bunch of noobs anyways, I really don't need your help.
Sorry, we must have mistaken you for the the original poster who asked for help. I suppose it's an easy mistake to make, considering you both have the same username.
Shannon Barber
Shannon Barber
Make a common base-class and overload new/delete in it. This lets you control which classes use your new & delete operators.

Make a #define for the __LINE__ __FILE__ debug version but call it something else.

#ifndef NDEBUG
#define MKH_NEW new
#else
#define MKH_NEW new(__LINE__, __FILE__)
#endif
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Drew_Benton
Drew_Benton
Magmai Kai Holmlor, I follow your second example, but as for the first, can you explain some on that please. Are you saying to make a base class and then derive everything that you use from that?
nilkn
nilkn
Quote:
Original post by Drew_Benton
Magmai Kai Holmlor, I follow your second example, but as for the first, can you explain some on that please. Are you saying to make a base class and then derive everything that you use from that?


Yes. He's saying have something like this:

class IMemManaged
{

// override new and delete here
};

Then, for everything you want to use the overriden new and delete operators, you derive them from IMemManaged. For example:

class Vec2 : public IMemManaged
{
float x, y;
// ...
}

Then, when new or delete is called on Vec2, it will use the overriden verion declared in IMemManaged.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.