difference in implementation between operator new and new []

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • C++Liliput

    difference in implementation between operator new and new []

    Hi,
    I was looking at the implementation of operator new and operator
    new[] in gcc source code and found that the implementation is exactly
    the same. The only difference is that the size_t argument passed to
    the operators is calculated correctly during runtime and passed in.
    Inside the implementation both operators (new and new[]) do a simple
    malloc(). Ditto for operator delete/delete[]. I have two questions:
    1) Who passes in the size_t argument at runtime?
    2) If the operator implementations are virtually the same (at least
    for gcc), can we assume that mismatched new[]/delete and new/delete[]
    calls will not result in any problem? I ask this because I was doing
    an exercise of finding memory leaks inside some C++ code. When I
    executed the code with Valgrind, I got a bunch of mismatched new[]/
    delete errors. However there were no reported memory leaks as such.
    However I assumed that doing a new[] and then a delete would most
    probably leak memory because delete would probably delete only the
    first object of the array (since the implementation of operator delete
    will not know about the array size). So I wrote a small C++ program
    where I do a lot of new[]'s and delete's on my Linux box and then
    monitored the memory footprint using the top command. However contrary
    to my expectations, there were no memory leaks. That is when I started
    looking into the implementation of operator new/new[] and operator
    delete/delete[] in gcc source code and found out that there is no
    difference in the internal implementation of the scalar and the
    corresponding vector operator.
  • tony_in_da_uk@yahoo.co.uk

    #2
    Re: difference in implementation between operator new and new []

    On Sep 24, 1:15 pm, "C++Liliput " <aveekmi...@gma il.comwrote:
    Hi,
    I was looking at the implementation of operator new and operator
    new[] in gcc source code and found that the implementation is exactly
    the same. The only difference is that the size_t argument passed to
    the operators is calculated correctly during runtime and passed in.
    Inside the implementation both operators (new and new[]) do a simple
    malloc(). Ditto for operator delete/delete[]. I have two questions:
    1) Who passes in the size_t argument at runtime?
    2) If the operator implementations are virtually the same (at least
    for gcc), can we assume that mismatched new[]/delete and new/delete[]
    calls will not result in any problem? I ask this because I was doing
    an exercise of finding memory leaks inside some C++ code. When I
    executed the code with Valgrind, I got a bunch of mismatched new[]/
    delete errors. However there were no reported memory leaks as such.
    However I assumed that doing a new[] and then a delete would most
    probably leak memory because delete would probably delete only the
    first object of the array (since the implementation of operator delete
    will not know about the array size). So I wrote a small C++ program
    where I do a lot of new[]'s and delete's on my Linux box and then
    monitored the memory footprint using the top command. However contrary
    to my expectations, there were no memory leaks. That is when I started
    looking into the implementation of operator new/new[] and operator
    delete/delete[] in gcc source code and found out that there is no
    difference in the internal implementation of the scalar and the
    corresponding vector operator.
    If new/delete and new[]/delete[] happen to be implemented on top of
    malloc()/free() in your implementation, and given that new[] must
    allocate contiguous memory in one block and that free() doesn't
    require the size_t as a parameter (the memory subsystem remembers the
    size anyway), this all hangs together. That's why it - observably -
    "works". What doesn't hang together is the construction and
    destruction of your elements: new[] and delete[] ensure each
    individual object has it's destructor or destructor called
    (respectively). Not using the correct operation doesn't give the
    compiler the opportunity to ensure this is done correctly. Even if
    you're working with POD data that ostensibly needs no construction/
    destruction, what you're doing is undefined by the Standard, and even
    a future revision of your compiler (let alone a different compiler/
    machine/OS) might not layer over malloc()/free() so transparently.
    You're asking for a crash.

    Cheers, Tony

    Comment

    • Kai-Uwe Bux

      #3
      Re: difference in implementation between operator new and new []

      C++Liliput wrote:
      Hi,
      I was looking at the implementation of operator new and operator
      new[] in gcc source code and found that the implementation is exactly
      the same. The only difference is that the size_t argument passed to
      the operators is calculated correctly during runtime and passed in.
      Inside the implementation both operators (new and new[]) do a simple
      malloc(). Ditto for operator delete/delete[]. I have two questions:
      1) Who passes in the size_t argument at runtime?
      It's computed magically by the implementation. See the example [5.3.4/12]:

      ? new T results in a call of operator new(sizeof(T)),
      ? ...
      ? new T[5] results in a call of operator new[](sizeof(T)*5+x) , and
      ? ...

      2) If the operator implementations are virtually the same (at least
      for gcc), can we assume that mismatched new[]/delete and new/delete[]
      calls will not result in any problem?
      a) You are relying on the behavior of a particular implementation and
      b) NO, not even with g++. Compile with g++ and run under valgrind:

      struct X {

      char * buffer;

      X ( void ) {
      buffer = new char;
      }

      ~X ( void ) {
      delete buffer;
      }

      };

      int main ( void ) {
      X* xp = new X [16];
      delete xp; // mismatch !
      }


      Best

      Kai-Uwe Bux

      Comment

      • korben dallas

        #4
        Re: difference in implementation between operator new and new []

        C++Liliput wrote:
        I was looking at the implementation of operator new and operator
        new[] in gcc source code and found that the implementation is exactly
        the same. The only difference is that the size_t argument passed to
        the operators is calculated correctly during runtime and passed in.
        Inside the implementation both operators (new and new[]) do a simple
        malloc(). Ditto for operator delete/delete[].
        OK.
        I have two questions:
        1) Who passes in the size_t argument at runtime?
        When the compiler generates the code for new-expression ('new' or
        'new[]' form), it also generates the code that will calculate the
        run-time size and pass it to 'operator new'/'operator new[]' functions.

        I hope you know that new-expression that you use in your code is not
        even remotely the same as 'operator new' function. The call to the
        'operator new' function is nothing but just a small part of what
        new-expression actually does. The same applies to delete-expression and
        'operator delete' function.
        2) If the operator implementations are virtually the same (at least
        for gcc), can we assume that mismatched new[]/delete and new/delete[]
        calls will not result in any problem?
        No. Why? In this question you must be referring to mismatched
        new-expression and delete-expression formats. Once again, the actual
        call to the appropriate 'operator new' function is just a small part of
        what new-expression translates to. The same applies to
        delete-expression. If you really want to know whether they are
        "compatible " in some particular implementation, you need to compare the
        entire code that is generated for these expressions, not just the code
        for 'operator new'/'operator delete'. The code for the expression is
        normally generated intrinsically, i.e. you won't find any "source code"
        for it in the library. You'll have analyze the assembly code, and do it
        for every possible combination of types, compiler settings, etc. This is
        a useless waste of time, if you ask me.
        I ask this because I was doing
        an exercise of finding memory leaks inside some C++ code. When I
        executed the code with Valgrind, I got a bunch of mismatched new[]/
        delete errors. However there were no reported memory leaks as such.
        Memory leaks? What made you to conclude that there must be memory leaks
        specifically? Mismatched new/delete result in undefined behavior.
        There's no way to predict how it will manifest itself. The belief in
        that it should specifically cause "memory leaks" is an urban legend. I
        don't know where it comes from.

        --
        Best regards,
        Andrey Tarasevich

        Comment

        Working...