Jump to content


TinyXML and Overriding new Operators


16 replies to this topic

#1 SpreeTree

    Valued Member

  • Members
  • PipPipPip
  • 265 posts

Posted 17 October 2005 - 09:11 PM

In my current engine, I override the new and delete operators using the following code


#ifdef _DEBUG
  #define MARY_DEBUG_NEW   new(__FILE__, __LINE__)
#else
  #define MARY_DEBUG_NEW   new
#endif

#define new                MARY_DEBUG_NEW


I then override the new operator with the following function calls

inline void *operator new(size_t size, const char *_file, int _line)
inline void *operator new[](size_t size, const char *_file, int _line)
inline void *operator new(size_t size)
inline void *operator new[](size_t size)

Each one of these calls HeapNew, which deals with the actual allocation of memory.

This seems to cause problems when I start to use XML.

When I include "tinyxml.h", it falls over on the line

rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));

with the error

error C2661: 'operator new' : no overloaded function takes 2 arguments

If I include the xml files with my MFC code (using the above new overrides), it falls over in the same place with the following errors

error C2665: 'operator new' : none of the 5 overloads can convert parameter 1 from type 'const char [74]'
  c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\new.h(100): could be 'void *operator new(size_t,const std::nothrow_t &) throw()'
  c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\new.h(108): or       'void *operator new(size_t,void *)'

Now I appreciate what the error is telling me, but I am unsure as to how to override the new operator again to deal with this one.

Any one encountered this before?

Thanks
Spree

#2 Reedbeta

    DevMaster Staff

  • Administrators
  • 4979 posts
  • LocationBellevue, WA

Posted 18 October 2005 - 12:39 AM

don't redefine new until after you've included the XML headerfile?

this would prevent you from tracing memory allocations in the XML module (assuming that's what you're doing), but then you shouldn't really need to anyway...
reedbeta.com - developer blog, OpenGL demos, and other projects

#3 corey

    Member

  • Members
  • PipPip
  • 78 posts

Posted 18 October 2005 - 12:53 AM

At a glance, it looks like the call with operator new in TinyXML is not allowing the translation to operator new (size_t, ...) .

Re-defining the actual keyword new is a bad idea. What happens when you define a class overload?

However, if you want to use it like MFC does, you must define it after includes and before implementations to avoid behavior described above.

corey

#4 SpreeTree

    Valued Member

  • Members
  • PipPipPip
  • 265 posts

Posted 18 October 2005 - 06:52 AM

Reedbeta said:

don't redefine new until after you've included the XML headerfile?

this would prevent you from tracing memory allocations in the XML module (assuming that's what you're doing), but then you shouldn't really need to anyway...

My memory management does more than just allow for the tracking of memory leaks, so I do want to track the use of new in tinyXML, and every other library that I use.

corey said:

Re-defining the actual keyword new is a bad idea.

Could you please expalin why? I appreciate it does cause me some problems (this one being a case in point) but as I mentioned above, I need (or want would be a better word) to track all memory allocation, so I need to override new to track allocation in external libraries.

Spree

#5 corey

    Member

  • Members
  • PipPip
  • 78 posts

Posted 18 October 2005 - 03:00 PM

It is bad when used in the manner you're showing.

If you re-defining it specifically before implementation that only uses new calls and not operator new calls, then it should be ok.

Do not re-define it before a class or in a header that might overload an operator new because then you're doing text replacement in the definition!

I say it's bad in general. It's ok within a specific context.

corey

#6 dave_

    Senior Member

  • Members
  • PipPipPipPip
  • 584 posts

Posted 18 October 2005 - 04:04 PM

SpreeTree said:

Could you please expalin why?

If you do that you cant subsequently overload operator new and delete as it replaces the keyword with arbitary things like MARY_DEBUG_NEW or new(__FILE__, __LINE__)

#7 SpreeTree

    Valued Member

  • Members
  • PipPipPip
  • 265 posts

Posted 18 October 2005 - 08:35 PM

dave_ said:

If you do that you cant subsequently overload operator new and delete as it replaces the keyword with arbitary things like MARY_DEBUG_NEW or new(__FILE__, __LINE__)

Ok , I see that, and it would be an issue if I intended to overwrite new in any other way, so I guess I am safe for now!

But, for future reference (and maybe for implementation now), what other way would produce the same effects?

Spree

#8 corey

    Member

  • Members
  • PipPip
  • 78 posts

Posted 19 October 2005 - 12:37 AM

Well, instead of redefining the actual "new" call, you could just define a different macro and use that in place of new and operator new.

You don't *have* to use the new keyword.

corey

#9 SpreeTree

    Valued Member

  • Members
  • PipPipPip
  • 265 posts

Posted 19 October 2005 - 06:58 AM

corey said:

You don't *have* to use the new keyword.

In my case, I do. The memory manager is there to not only cover the memory allocation in my native code, but to track memory allocation throught the application, including the various libraries I use.

If I didn't redefine the new keyword, then I would not be getting the required information from my external libraries (granted I still don't get all of it, but most is better then none), and people using my code would have to use a different keyword for the same ends, which I don't want to force on them.

Spree

#10 ThomasYoung

    New Member

  • Members
  • Pip
  • 5 posts

Posted 19 October 2005 - 08:12 AM

[edit]Hmm.. ignore the following, I just noticed that you need file and line. ;-D[edit]

You should be able to achieve what you want without messing around with macros at all.
If you define non-inline replacements for the global operators somewhere in your project then the linker should use these in preference to the built-in versions.
These definitions can then be wrapped by #ifdef DEBUG.

e.g. (in a .cpp somewhere in your project):

#ifdef DEBUG

#include <stdlib.h>


void PlatformDebugBreak();


static unsigned long totalAllocated = 0;

static unsigned long maximumAllocated = 0;


void*

operator new(size_t size)

{

    size_t sizeToMalloc = size + sizeof(size_t);

    size_t* result = reinterpret_cast<size_t*>(malloc(sizeToMalloc));

    if(sizeToMalloc && !result)

    {

        PlatformDebugBreak();

    }

    totalAllocated += size;

    if(totalAllocated > maximumAllocated)

    {

        maximumAllocated = totalAllocated;

    }

    *result = size;

    return result + 1;

}

void

operator delete(void* ptr)

{

    if(!ptr)

    {

        return;

    }

    size_t* ptrToSizeT = reinterpret_cast<size_t*>(ptr);

    --ptrToSizeT;

    totalAllocated -= *ptrToSizeT;

    free(ptrToSizeT);

}

void*

operator new[](size_t size)

{

    size_t sizeToMalloc = size + sizeof(size_t);

    size_t* result = reinterpret_cast<size_t*>(malloc(sizeToMalloc));

    if(sizeToMalloc && !result)

    {

        PlatformDebugBreak();

    }

    totalAllocated += size;

    if(totalAllocated > maximumAllocated)

    {

        maximumAllocated = totalAllocated;

    }

    *result = size;

    return result + 1;

}

void

operator delete[](void* ptr)

{

    if(!ptr)

    {

        return;

    }

    size_t* ptrToSizeT = reinterpret_cast<size_t*>(ptr);

    --ptrToSizeT;

    totalAllocated -= *ptrToSizeT;

    free(ptrToSizeT);

}

#endif



#11 SpreeTree

    Valued Member

  • Members
  • PipPipPip
  • 265 posts

Posted 19 October 2005 - 09:14 AM

ThomasYoung said:

]Hmm.. ignore the following, I just noticed that you need file and line. ;-D

Unfortunatly yes. Its normally not important but does help with the tracking of memory leaks (allowing you to double click in the output stream of Dev Studio and go straight to the file and line), and is something i cant live without.

Spree

#12 grinliz

    New Member

  • Members
  • Pip
  • 2 posts

Posted 19 October 2005 - 05:47 PM

I pushed a new version of TinyXML (2.4.2) that should fix the overloaded new and delete problem.

lee

#13 corey

    Member

  • Members
  • PipPip
  • 78 posts

Posted 19 October 2005 - 07:39 PM

SpreeTree said:

In my case, I do. The memory manager is there to not only cover the memory allocation in my native code, but to track memory allocation throught the application, including the various libraries I use.

In that case, you'll just have to make it work by ensuring the re-definition is past any awkward headers.

It looks like the TinyXML author has shown up? I've been meaning to ask him about parsing well-formed strict XHTML with it.

corey

#14 SpreeTree

    Valued Member

  • Members
  • PipPipPip
  • 265 posts

Posted 19 October 2005 - 08:41 PM

grinliz said:

I pushed a new version of TinyXML (2.4.2) that should fix the overloaded new and delete problem.

lee

Excellent.

Thanks for the swift fix Lee, I'll try and download the new version tonight and let you know how it does :)

Spree

#15 grinliz

    New Member

  • Members
  • Pip
  • 2 posts

Posted 19 October 2005 - 08:57 PM

corey -

Well formed strict XMTML is probably a better topic for the TinyXML forums on Sourceforge. (Especially since I haven't tried it, but others there have.)

grinliz

#16 corey

    Member

  • Members
  • PipPip
  • 78 posts

Posted 19 October 2005 - 09:19 PM

No worries, it was just a comment.

corey

#17 SpreeTree

    Valued Member

  • Members
  • PipPipPip
  • 265 posts

Posted 19 October 2005 - 09:37 PM

Version 2.4.2 works a treat, thanks for that! :)

Spree





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users