Customize operator new / delete

Discussion in 'C++' started by Nephi Immortal, May 8, 2011.

  1. 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;
    }
     
    Nephi Immortal, May 8, 2011
    #1
    1. Advertising

  2. Nephi Immortal

    Ian Collins Guest

    On 05/ 8/11 02:11 PM, Nephi Immortal wrote:
    > 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.

    --
    Ian Collins
     
    Ian Collins, May 8, 2011
    #2
    1. Advertising

  3. Nephi Immortal

    James Kanze Guest

    On May 8, 3:11 am, Nephi Immortal <> wrote:
    > 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).

    --
    James Kanze
     
    James Kanze, May 8, 2011
    #3
  4. On May 8, 12:05 pm, "io_x" <> wrote:
    > "James Kanze" <> ha scritto nel messaggionews:...
    >
    > > 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();

    >
    > 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.

    >
    >
    >
    > >        }
    > >        return result;
    > >    }- Hide quoted text -

    >
    > - Show quoted text -
     
    Nephi Immortal, May 8, 2011
    #4
  5. On May 8, 11:44 am, "io_x" <> wrote:
    > "Nephi Immortal" <> ha scritto nel messaggionews:...
    >
    > > 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 -
     
    Nephi Immortal, May 8, 2011
    #5
  6. Nephi Immortal

    Ian Collins Guest

    On 05/ 9/11 10:35 AM, Nephi Immortal wrote:
    > On May 8, 12:05 pm, "io_x"<> wrote:
    >> "James Kanze"<> ha scritto nel messaggionews:...
    >>
    >>> 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();

    >>
    >> 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.


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

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

    --
    Ian Collins
     
    Ian Collins, May 8, 2011
    #6
  7. Nephi Immortal

    James Kanze Guest

    On May 8, 6:05 pm, "io_x" <> wrote:
    > "James Kanze" <> ha scritto nel messaggionews:...


    > > 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();


    > 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.

    --
    James Kanze
     
    James Kanze, May 10, 2011
    #7
  8. Nephi Immortal

    James Kanze Guest

    On May 9, 7:47 am, "io_x" <> wrote:
    > "Nephi Immortal" <> ha scritto nel messaggionews:...


    [...]
    > 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.

    --
    James Kanze
     
    James Kanze, May 10, 2011
    #8
  9. Nephi Immortal

    James Kanze Guest

    On May 11, 8:31 am, "io_x" <> wrote:
    > "James Kanze" <> ha scritto nel messaggionews:...
    > > On May 8, 6:05 pm, "io_x" <> wrote:
    > >> "James Kanze" <> ha scritto nel
    > >> messaggionews:...


    > >> > 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();


    > >> 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.


    > 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.)

    --
    James Kanze
     
    James Kanze, May 15, 2011
    #9
  10. Nephi Immortal

    James Kanze Guest

    On May 11, 8:56 am, "io_x" <> wrote:
    > "io_x" <> ha scritto nel
    > messaggionews:4dca3b03$0$38643$...


    [...]
    > 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.

    --
    James Kanze
     
    James Kanze, May 15, 2011
    #10
  11. On May 15, 6:14 am, James Kanze <> wrote:
    > 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".
     
    Joshua Maurice, May 16, 2011
    #11
  12. Nephi Immortal

    Ian Collins Guest

    On 05/16/11 06:54 PM, Joshua Maurice wrote:
    > On May 15, 6:14 am, James Kanze<> wrote:
    >> 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".


    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.

    --
    Ian Collins
     
    Ian Collins, May 16, 2011
    #12
  13. Nephi Immortal

    Nobody Guest

    On Sun, 15 May 2011 23:54:10 -0700, Joshua Maurice wrote:

    > 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.
     
    Nobody, May 16, 2011
    #13
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. HeroOfSpielburg
    Replies:
    1
    Views:
    411
    Alf P. Steinbach
    Aug 6, 2003
  2. Jef Driesen
    Replies:
    1
    Views:
    526
    Gernot Frisch
    Jan 19, 2005
  3. Amy
    Replies:
    13
    Views:
    6,058
    Kurt Stutsman
    Feb 23, 2005
  4. tom
    Replies:
    5
    Views:
    429
  5. X X
    Replies:
    4
    Views:
    370
    red floyd
    Jul 19, 2010
Loading...

Share This Page