Customize operator new / delete

N

Nephi Immortal

I decide to customize my own operator new and operator delete in the
global scope. They are independent outside class as long as they are
not function members of any class.
Please confirm if my code is valid as C++ standard states. I had
examined across website via google search. I only find user-defined
classes, but not for global scope.

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

inline
void *operator new( size_t size ) { return malloc( size ); }

inline
void *operator new[]( size_t size ) { return malloc( size ); }

inline
void operator delete( void *pUserData ) { free( pUserData ); }

inline
void operator delete[]( void *pUserData ) { free( pUserData ); }

int main()
{
char *p = new char[ 100 ];
delete [] p;

return 0;
}
 
I

Ian Collins

I decide to customize my own operator new and operator delete in the
global scope. They are independent outside class as long as they are
not function members of any class.
Please confirm if my code is valid as C++ standard states. I had
examined across website via google search. I only find user-defined
classes, but not for global scope.

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

inline
void *operator new( size_t size ) { return malloc( size ); }

inline
void *operator new[]( size_t size ) { return malloc( size ); }

inline
void operator delete( void *pUserData ) { free( pUserData ); }

inline
void operator delete[]( void *pUserData ) { free( pUserData ); }

int main()
{
char *p = new char[ 100 ];
delete [] p;

return 0;
}

The code is fine, but I'd drop the "inline". The draft C++0x standard
prohibits it.
 
J

James Kanze

I decide to customize my own operator new and operator delete
in the global scope. They are independent outside class as
long as they are not function members of any class.
Please confirm if my code is valid as C++ standard states. I
had examined across website via google search. I only find
user-defined classes, but not for global scope.
#include <stdio.h>
#include <malloc.h>
inline
void *operator new( size_t size ) { return malloc( size ); }
inline
void *operator new[]( size_t size ) { return malloc( size ); }
inline
void operator delete( void *pUserData ) { free( pUserData ); }
inline
void operator delete[]( void *pUserData ) { free( pUserData ); }
int main()
{
char *p = new char[ 100 ];
delete [] p;
return 0;
}

The operator new do not meet the requirements set down in the
standard, particularly the post-condition that the returned
pointer is never null. You have to do something like:

void operator new( size_t size )
{
void* result = malloc( size );
if ( result == NULL ) {
throw std::bad_alloc();
}
return result;
}

Also, the implementations are not allowed to be inlined
(doubtlessly because the standard library is required to use
them if they are present, and the code in the standard library
has already been compiled expecting them not to be inlined).
 
N

Nephi Immortal

for me better what does malloc(); it return 0, so each function know
the path they have to follow: the error path; each function for its
responsability.

You are correct to say this way. I don’t need to use neither throw()
nor exception. The allocation failure will be reported to the error
handler and malloc sets errno to ENOMEM if a memory allocation fails.
The allocation failure is tested at startup before the program begins
to run until it ends prior deallocation memory. If error is reported,
then the program will be terminated immediately.
 
N

Nephi Immortal

Nephi Immortal said:
I decide to customize my own operator new and operator delete in the
global scope.  They are independent outside class as long as they are
not function members of any class.
Please confirm if my code is valid as C++ standard states.  I had
examined across website via google search.  I only find user-defined
classes, but not for global scope.
#include <stdio.h>
#include <malloc.h>

for the C language the header of malloc() function is not malloc.h
but stdlib.h; possiblily you not call the malloc() of the C language...
inline
void *operator new( size_t size ) { return malloc( size ); }
inline
void *operator new[]( size_t size ) { return malloc( size ); }

this should be wrong because the right malloc size here is
malloc(size*sizeof(*pointerType))
but who know how to get the number sizeof(*pointerType)?

No, you are wrong unless you don’t need to put sizeof() on malloc()
function inside operator new function because size_t size parameter of
operator new function is already provided the sizeof( type ) times
elements by C++ Compiler.
Test it yourself until you find out. You will always need to use
sizeof() if you place malloc() function somewhere.

inline
void operator delete( void *pUserData ) { free( pUserData ); }
inline
void operator delete[]( void *pUserData ) { free( pUserData ); }
int main()
{
char *p = new char[ 100 ];

here you are lucky for delete but what about
 int *p = new int[ 100 ];
if is call the new above it reserve space for one
array of 100 chars not one array of 100 ints

The buffer overruns NEVER happens because C++ Compiler knows the
size. It will recognize int type and add four bytes each element in
the int array.
delete [] p;

i never understand that; excuse if i speak too much


return 0;
}- Hide quoted text -

- Show quoted text -
 
I

Ian Collins

You are correct to say this way. I don’t need to use neither throw()
nor exception. The allocation failure will be reported to the error
handler and malloc sets errno to ENOMEM if a memory allocation fails.
The allocation failure is tested at startup before the program begins
to run until it ends prior deallocation memory. If error is reported,
then the program will be terminated immediately.

If you want a no-throw allocation, use the alternative standard form:

operator new(std::size_t, const std::nothrow_t&);
 
J

James Kanze

"James Kanze" <[email protected]> ha scritto nel messaggionews:[email protected]...
for me better what does malloc(); it return 0, so each function know
the path they have to follow: the error path; each function for its
responsability.

I'd argue about that (although most of the applications I've
worked on have set the new handler to abort). Still, if you're
providing replacement for the standard operator new, you don't
have a choice. One of the post-conditions that must be met is
that you return a valid non-null pointer. And a lot of code
(e.g. in the standard library) counts on it, and will fail
otherwise.
 
J

James Kanze

"Nephi Immortal" <[email protected]> ha scritto nel messaggio
[...]
but i don't understand well too why use 2 delete function
if they do the same:

Because they aren't required to do the same. If the two
operator new do something different, then the two operator
delete must also. Typically, of course, operator new[] will
just call operator new, and operator delete[] will just call
operator delete. The standard also guarantees this for the
library implementations, so if you just overload operators new
and delete, you should catch all of the memory allocations.
 
J

James Kanze

but the C++ libraries are linked with the new, delete of C++,
right?

It depends. The standard requires that the implementation
provide some means of replacing the standard operators new and
delete. How the implementation does it (and what additional
commands it might require) is up to it. If the C++ libraries
are really libraries (and not fully linked DLL's), then this
will typically be trivial; separate object files in a library
are not yet linked, and the object file containing the standard
operators new and delete will only be linked into the program if
they resolve an otherwise unresolved external.
there is a conflict for some other new, delete, defined in some
other place?
The .asm result seems to indicate there is a name conflict
because the name of new[] operator is always "@$bnwa$qui" for both
[std new[] and defined new[] ];
but the .exe result show there is no conflict because the real name of the
new, delete of the standard C++ in this compiler is different; something
as __org_.. show in the debugger different from "operator new"
show in the debugger
so locally here it seems, there is no problem and the two function
new[] are recognise different; ok from the sys and for what i think
should be right

operator new() and operator new[]() are two different functions,
with two different names. (What the standard does require is
that the standard operator new[] call operator new() to obtain
its memory.)
 
J

James Kanze

"io_x" <[email protected]> ha scritto nel
messaggio
[...]
i mean libraries == file libraries .dll

Technically speaking, DLLs are not libraries, although the name
seems to have stuck. Except in very rare cases, you should not
link the C++ standard library as a DLL, but statically.
 
J

Joshua Maurice

Except in very rare cases, you should not
link the C++ standard library as a DLL, but statically.

Wait what? IIRC, msvc in newer versions has even removed the option of
statically linking to the C++ standard library (the C runtime library
or whatever Microsoft calls it).

Also, I know I've heard about fun results that can happen in Windows
if you have two different DLLs that both statically link to the C
runtime, and try to allocate memory in one DLL and free that object in
the other DLL.

I just want to point out that your advice is clearly wrong for
Windows. As a programmer, one should educate oneself a bit about your
platform or platforms, and then make an informed decision. And that
informed decision will not /not/ be "almost always statically link
against the C++ standard library".
 
I

Ian Collins

Wait what? IIRC, msvc in newer versions has even removed the option of
statically linking to the C++ standard library (the C runtime library
or whatever Microsoft calls it).

Also, I know I've heard about fun results that can happen in Windows
if you have two different DLLs that both statically link to the C
runtime, and try to allocate memory in one DLL and free that object in
the other DLL.

I just want to point out that your advice is clearly wrong for
Windows. As a programmer, one should educate oneself a bit about your
platform or platforms, and then make an informed decision. And that
informed decision will not /not/ be "almost always statically link
against the C++ standard library".

That can be extrapolated to other platforms as well. There isn't a
static C++ standard library provided for (Open)Solaris. Indeed if there
were, it would make interposing user provided new and delete operator a
lot harder.
 
N

Nobody

Also, I know I've heard about fun results that can happen in Windows
if you have two different DLLs that both statically link to the C
runtime, and try to allocate memory in one DLL and free that object in
the other DLL.

This issue exists regardless of whether you link statically or dynamically.
 

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,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top