Search code examples
c++arraysmemory-managementnew-operator

Why is there a special new and delete for arrays?


What is wrong with using delete instead of delete[]?

Is there something special happening under the covers for allocating and freeing arrays?

Why would it be different from malloc and free?


Solution

  • Objects created with new[] must use delete[]. Using delete is undefined on arrays.

    With malloc and free you have a more simple situation. There is only 1 function that frees the data you allocate, there is no concept of a destructor being called either. The confusion just comes in because delete[] and delete look similar. Actually they are 2 completely different functions.

    Using delete won't call the correct function to delete the memory. It should call delete[](void*) but instead it calls delete(void*). For this reason you can't rely on using delete for memory allocated with new[]

    See this C++ FAQ

    [16.13] Can I drop the [] when deleteing array of some built-in type (char, int, etc)?

    No!

    Sometimes programmers think that the [] in the delete[] p only exists so the compiler will call the appropriate destructors for all elements in the array. Because of this reasoning, they assume that an array of some built-in type such as char or int can be deleted without the []. E.g., they assume the following is valid code:

    void userCode(int n)  {
        char* p = new char[n];
        ...
        delete p; // ← ERROR! Should be delete[] p !
    }
    

    But the above code is wrong, and it can cause a disaster at runtime. In particular, the code that's called for delete p is operator delete(void*), but the code that's called for delete[] p is operator delete[](void*). The default behavior for the latter is to call the former, but users are allowed to replace the latter with a different behavior (in which case they would normally also replace the corresponding new code in operator new[](size_t)). If they replaced the delete[] code so it wasn't compatible with the delete code, and you called the wrong one (i.e., if you said delete p rather than delete[] p), you could end up with a disaster at runtime.

    Why does delete[] exist in the first place?

    Whether you do x or y:

     char * x = new char[100]; 
     char * y = new char;
    

    Both are stored in char * typed variables.

    I think the reason for the decision of delete, and delete[] goes along with a long list of decisions that are in favor of efficiency in C++. It is so that there is no enforced price to do a lookup of how much needs to be deleted for a normal delete operation.

    Having 2 new and new[] seems only logical to have delete and delete[] anyway for symmetry.