Archived

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

beaton_john

custom operator new -- arrgh!

Recommended Posts

Watup, I am pissed (sic). What i have done is write a memory manager, with custom operator new. It is working very satisfactorily in that it will allocate data. HOWEVER. I get about 1000+ references because basic_string allocates lots of memory using the new operator. How can i use my operator new for my things, and the standard operator new for std::string, std::vector, etc? There is only one line with #include <string> (all others reference the header), so i''m hoping that i can simply put something around the include to stop it.... Thanks in advance, JB

Share this post


Link to post
Share on other sites
I can think of a number of solutions. All bad.

Bad solution number 1:

struct DUMMY {};
const DUMMY dummy;

inline void * __cdecl operator new(size_t size, DUMMY) {
// your code here

}

#define NEW_THUNK new (dummy)
#define new NEW_THUNK

This has so many problems, I hesitate to admit that it even occured to me. With this "solution," headers you want to exclude from using your custom allocator, you wrap with #undef new and #define new NEW_THUNK . (Strictly speaking the NEW_THUNK #define isn''t necessary, but the alternative is #define new new (dummy) and seeing that on my screen makes my toes curl.

One problem is that it doesn''t (and can''t) disambiguate operator delete, so the same version of delete would be called for both your new and standard new. This could either be an annoyance or a deal breaker, depending on what your custom memory manager does. Another problem is that it completely clobbers all new expressions so things like placement new and class overrides die horribly. Also, there are potential issues with remembering to wrap headers consistently.

Bad solution number 2:
This isn''t actually that bad a solution. Just write a custom allocator that bypasses your operator new, and always use it with STL containers. The downside is that it''s potentially a lot of extra typing, and you have to do extra code all over the place instead in just a few places.

Bad solution number 3:
Write a custom allocator that bypasses your operator new, and hack your STL header files to use that allocator instead of the standard allocator. This localizes the changes that need to be done, so it''s less extra work than the previous solution, but do I even need to list the downside here?

Bad solution number 4:
Rewrite your operator new implementation as a class operator new. Then derive all the classes you plan to use with your custom allocator from this base class. The downside is extra dependencies and you can''t use your operator new on primitive types or classes that you didn''t write.

Maybe I can think of a less bad solution with more sleep.

Share this post


Link to post
Share on other sites
Solution 1 is not so bad. It would work just fine, granted it would be a little ugly but still. It will get the job done. Just dont use NEW_THUNK, use #define new new instead it looks prettier.

| C++ Debug Kit :: GameDev Kit :: DirectX Tutorials :: 2D DX Engine | TripleBuffer Software |
| Plug-in Manager :: System Information Class :: D3D9 Hardware Enum | DevMaster :: FlipCode |

Share this post


Link to post
Share on other sites
Cheerz.

My new function automatically logs allocations (if _DEBUG) so i just made it


inline void * __cdecl operator new(size_t size, const char* line, const char* file)
{
// log line and file...

}

#define new new(__LINE__, __FILE__);



so now it works !

Share this post


Link to post
Share on other sites
quote:
Original post by Namethatnobodyelsetook
Define new, delete, new[], delete[] in a baseclass. Derive everything from that base class. Your new will only be called for your classes.


Will not work. The size argument passed to the class overloaded new will be the size of the base class, not the derived one so you will not allocate enough memory. For your idea to work you would have to overload new/delete for each and every class.

Share this post


Link to post
Share on other sites
The new expression will pass the correct size to the class operator new for new expressions for derived classes. Overriding new/delete in every derived class is not necessary.

Share this post


Link to post
Share on other sites
Declare your operator new/delete after you include string.

--------
"Hey, what about those baggy pants you kids are wearin'' these days? Aren''t they hip and cool and poppin'' fresh?"-Peter Griffin
"Everytime I see an M followed by a dollar sign I just say "oh god" and go to the next post."-Neurokaotix
the D programming language|google|msdn|XLib reference manual

Share this post


Link to post
Share on other sites
quote:
Original post by SiCrane
The new expression will pass the correct size to the class operator new for new expressions for derived classes. Overriding new/delete in every derived class is not necessary.


My bad, you''re right. However, there can be some complications if you use base class'' operator new/delete for a derived class. Item 8 in Effective C++ addresses this issue well.

Share this post


Link to post
Share on other sites