Overriding new and delete.

G

groleo

Hi list.

Simple question:
is it possible to override the global new/delete operators, without
using malloc/free?
I mean something in the ideea of the code below, which doesnt work
cause of
the recursivenes.
What I'm trying to say is how to override new/delete using the original
global
operators? ( if this is possible )


#include <stdio.h>
#include <malloc.h>
#include <new>

void*
operator new( size_t sz )
{
printf( "new\n" ) ;
return ::eek:perator new( sz );
//return malloc( sz );
}

void
operator delete( void* p )
{
printf( "delete\n" ) ;
::eek:perator delete( p );
//free( p ) ;
}


int
main()
{
int* i = new(int) ;
delete i;
return 0;
}
 
A

Axter

Hi list.

Simple question:
is it possible to override the global new/delete operators, without
using malloc/free?
I mean something in the ideea of the code below, which doesnt work
cause of
the recursivenes.
What I'm trying to say is how to override new/delete using the original
global
operators? ( if this is possible )


#include <stdio.h>
#include <malloc.h>
#include <new>

void*
operator new( size_t sz )
{
printf( "new\n" ) ;
return ::eek:perator new( sz );
//return malloc( sz );
}

void
operator delete( void* p )
{
printf( "delete\n" ) ;
::eek:perator delete( p );
//free( p ) ;
}


int
main()
{
int* i = new(int) ;
delete i;
return 0;
}

Are you trying to do this because you're having problems when you call
malloc and free.
Be aware that if you try to use the above code for some type of
debugging logic, you could experience problems if you connect to a
module that uses a different library with different allocators that are
not compatible.
The best way to handle this, is to move the operators into a header,
and make them an inline function.
Example:
inline void operator delete(void* memblock)
{
free(memblock);
leaktracker61_log_delete_obj_mem(memblock, 0);
}
inline void operator delete[](void* memblock)
{
free(memblock);
leaktracker61_log_delete_obj_mem(memblock, 1);
}
inline void * operator new(size_t bytes, const char *file, int line,
const char* FunctionName){
return leaktracker61_log_new_obj_mem(malloc(bytes), 0, file, line,
FunctionName);
}

inline void * operator new[](size_t bytes, const char *file, int line,
const char* FunctionName){
return leaktracker61_log_new_obj_mem(malloc(bytes), 1, file, line,
FunctionName);
}


Notice in the above code, that the new operators call malloc(), and
pass the result to the real debugging function.
By using this inline method, you can insure that the right allocators
and deallocators are called, and still be able to pass on the debugging
information to your target debugging logic.
For more info, and a full example, check out the following link, which
has a free leak tracking program:
http://code.axter.com/leaktracker.h

You can download the associated DLL & LIB file via following link:
http://code.axter.com/leaktracker.zip
 
H

Howard Hinnant

"Axter said:
Exactly what is a bad idea?
Are you referring to item 9 in above link? If not, which item?

Item 404. Sorry, my browser took me right there with the trailing #404.
I thought it would for you too.

-Howard
 
A

Axter

Howard said:
Item 404. Sorry, my browser took me right there with the trailing #404.
I thought it would for you too.

-Howard
After I clicked it the second time, it took me there.
I don't completely agree with the rationale on that item.
Specifically, the last part of the Rationale:
****************************************************
, and is believed to be of limited value.
****************************************************

I've seen this used in other debug or leak tracking implementations.
 
H

Howard Hinnant

"Axter said:
After I clicked it the second time, it took me there.
I don't completely agree with the rationale on that item.
Specifically, the last part of the Rationale:
****************************************************
, and is believed to be of limited value.
****************************************************

I've seen this used in other debug or leak tracking implementations.

It sure would be easy to forget to include your inlined operator new in
one of your translation units, and silently get the system operator new.
That pointer could then be passed to another translation unit which did
remember to include the inlined operators and subsequently be deleted by
your (possibly incompatible) inlined operator delete.

By making your operators not inlined, the linker will guarantee that you
have only one definition of these operators in your program.

If you're concerned about different operator definitions across shared
library boundaries, join the club. So am I. :) But making them inline
now means you need to worry about different operator definitions across
translation unit boundaries. Imho it makes the problem worse.

What happens if you don't have access to all translation units from
which you're taking ownership of a new'd pointer? This could easily
happen with use of <strstream> (for example), or possibly even
get_temporary_buffer from <memory>. Your std::lib may hand you a
pointer allocated from the system new and you'll deallocate it with your
custom delete.

I've written leak checkers myself. They're an incredibly useful tool.
In my experience they work fine with non-inlined operators.

-Howard
 
G

groleo

After looking at libstdc++ and the 1998 c++ draft, it is recomended
that
new and delete should use malloc and free, so I would answer myself :p,
that the global operators can't be overloaded makeing use of the
original ones.

Another thing with Axter example is that when you overload this type of
"new":
void * operator new[](size_t bytes, const char *file, int line,
const char* FunctionName)
that is new (2,f) T ;
you might get some errors at statements that allready have their
(new-placement) used.

Anyway it would be nice if some compilers/libraries provided debug
versions
of new and delete.
 
P

Pete Becker

After looking at libstdc++ and the 1998 c++ draft, it is recomended
that
new and delete should use malloc and free, so I would answer myself :p,
that the global operators can't be overloaded makeing use of the
original ones.

The other thing that's important to notice in the standard is that these
functions are described as "replaceable". When you provide your own
(with the particular signatures at issue), you "displace" the ones
provided by the library.
 
A

Axter

Howard said:
It sure would be easy to forget to include your inlined operator new in
one of your translation units, and silently get the system operator new.
That pointer could then be passed to another translation unit which did
remember to include the inlined operators and subsequently be deleted by
your (possibly incompatible) inlined operator delete.

By making your operators not inlined, the linker will guarantee that you
have only one definition of these operators in your program.

If you're concerned about different operator definitions across shared
library boundaries, join the club. So am I. :) But making them inline
now means you need to worry about different operator definitions across
translation unit boundaries. Imho it makes the problem worse.

What happens if you don't have access to all translation units from
which you're taking ownership of a new'd pointer? This could easily
happen with use of <strstream> (for example), or possibly even
get_temporary_buffer from <memory>. Your std::lib may hand you a
pointer allocated from the system new and you'll deallocate it with your
custom delete.

Experts like Herb Sutter, recommend that if you create it, then you
should delete it.
In other words, if your translation unit creates an object, then it
should be responsible for deleting the object.
You should not pass it on to another translation unit.
I've written leak checkers myself. They're an incredibly useful tool.
In my experience they work fine with non-inlined operators.

-Howard

It's been my experience, that they don't work when not using inline
method.
In order for it to work in a non-inline mode, then you would have to
compile the leaktracker.dll with the same runtime library.
I have not had any problems using the inline method, and I've tested it
in multiple compilers, and multiple platforms.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,739
Latest member
Clint8040

Latest Threads

Top