Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I'm just going to direct you to this answer: <a href="https://stackoverflow.com/questions/240212/what-is-the-difference-between-newdelete-and-mallocfree#240308">What is the difference between new/delete and malloc/free?</a> . Martin provided an excellent overview. Quick overview on how they <em>work</em> (without diving into how you could overload them as member functions):</p> <h2>new-expression and allocation</h2> <ol> <li>The code contains a new-expression supplying the type-id. </li> <li>The compiler will look into whether the type overloads the operator new with an allocation function. </li> <li>If it finds an overload of an operator new allocation function, that one is called using the arguments given to new and sizeof(TypeId) as its first argument:</li> </ol> <p>Sample:</p> <pre><code>new (a, b, c) TypeId; // the function called by the compiler has to have the following signature: operator new(std::size_t size, TypeOfA a, TypeOfB b, TypeOf C c); </code></pre> <ol> <li>if operator new fails to allocate storage, it can call <code>new_handler</code>, and hope it makes place. If there still is not enough place, new has to throw <code>std::bad_alloc</code> or derived from it. An allocator that has <code>throw()</code> (no-throw guarantee), it shall return a null-pointer in that case. </li> <li>The C++ runtime environment will create an object of the type given by the type-id in the memory returned by the allocation function. </li> </ol> <p>There are a few special allocation functions given special names:</p> <ul> <li><code>no-throw</code> new. That takes a <code>nothrow_t</code> as second argument. A new-expression of the form like the following will call an allocation function taking only std::size_t and nothrow_t:</li> </ul> <p>Example:</p> <pre><code>new (std::nothrow) TypeId; </code></pre> <ul> <li><code>placement new</code>. That takes a void* pointer as first argument, and instead of returning a newly allocated memory address, it returns that argument. It is used to create an object at a given address. Standard containers use that to preallocate space, but only create objects when needed, later.</li> </ul> <p>Code:</p> <pre><code>// the following function is defined implicitly in the standard library void * operator(std::size_t size, void * ptr) throw() { return ptr; } </code></pre> <p>If the allocation function returns storage, and the the constructor of the object created by the runtime throws, then the operator delete is called automatically. In case a form of new was used that takes additional parameters, like </p> <pre><code>new (a, b, c) TypeId; </code></pre> <p>Then the operator delete that takes those parameters is called. That operator delete version is only called if the deletion is done because the constructor of the object did throw. If you call delete yourself, then the compiler will use the normal operator delete function taking only a <code>void*</code> pointer:</p> <pre><code>int * a = new int; =&gt; void * operator new(std::size_t size) throw(std::bad_alloc); delete a; =&gt; void operator delete(void * ptr) throw(); TypeWhosCtorThrows * a = new ("argument") TypeWhosCtorThrows; =&gt; void * operator new(std::size_t size, char const* arg1) throw(std::bad_alloc); =&gt; void operator delete(void * ptr, char const* arg1) throw(); TypeWhosCtorDoesntThrow * a = new ("argument") TypeWhosCtorDoesntThrow; =&gt; void * operator new(std::size_t size, char const* arg1) throw(std::bad_alloc); delete a; =&gt; void operator delete(void * ptr) throw(); </code></pre> <h2>new-expression and arrays</h2> <p>If you do </p> <pre><code>new (possible_arguments) TypeId[N]; </code></pre> <p>The compiler is using the <code>operator new[]</code> functions instead of plain <code>operator new</code>. The operator can be passed a first argument not exactly <code>sizeof(TypeId)*N</code>: The compiler could add some space to store the number of objects created (necassary to be able to call destructors). The Standard puts it this way:</p> <ul> <li><code>new T[5]</code> results in a call of operator <code>new[](sizeof(T)*5+x)</code>, and</li> <li><code>new(2,f) T[5]</code> results in a call of operator <code>new[](sizeof(T)*5+y,2,f)</code>.</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload