Is Delete[] Equal to Delete

Is delete[] equal to delete?

Whether this leads to a memory leak, wipes your hard disk, gets you pregnant, makes nasty Nasal Demons chasing you around your apartment, or lets everything work fine with no apparent problems, is undefined. It might be this way with one compiler, and change with another, change with a new compiler version, with each new compilation, with the moon phases, your mood, or depending on the number of neutrinos that passed through the processor on the last sunny afternoon. Or it might not.

All that, and an infinite number of other possibilities are put into one term: Undefined behavior:

Just stay away from it.

delete vs delete[] [duplicate]

From the standard (5.3.5/2) :

In the first alternative (delete
object), the value of the operand of
delete shall be a pointer to a
non-array object or a pointer to a
sub-object (1.8) representing a base
class of such an object (clause 10).
If not, the behavior is undefined.

In the second alternative (delete
array), the value of the operand of
delete shall be the pointer value
which resulted from a previous array
new-expression. If not, the
behavior is undefined.

So no : they are in no way equivalent !

Is delete and delete[] equivalent for basic data types

If you use new you need to use delete

If you use new [] you have to use delete []

They mean different things. double* d = new double(); means allocate and construct a double type. delete d; means unallocated and destruct a single double type. double* d = new double[NUM_VALUES]; means allocate NUM_VALUES doubles and delete [] d means unallocated each of of the NUM_VALUES doubles allocated.

delete[] vs delete in a for loop [duplicate]

Both versions of new and delete each have two tasks: allocation/deallocation and construction/destruction.

  • new will allocate memory and call a constructor.

  • delete will call a deconstructor and deallocate memory.

  • new [] allocates single chunk of memory and then calls a constructor possibly several times.

  • delete [] calls a deconstructor possibly several times and then deallocates a single chunk of memory.

So using delete multiple times means deallocating multiple chunks of memory whereas using delete[] will deallocate a single chunk of memory; using delete multiple times is not equivalent to using delete [].

delete x vs ::operator delete(x)

delete x is a delete expression.

::operator delete(x) is a deallocation function.

The delete expression will call the destructor (if it exists) and then the deallocation function. Calling the deallocation function directly will bypass the destructor.

Is delete[] equal to per element delete. c++

The expression delete[] data must match the new T[] that created the array on the heap, so that T is the type of *data. Otherwise the behavior of the program is undefined (5.3.5).

In your example, the type of data and *data is unknown. If T is not char, the behavior is undefined.

You should not call delete[] data, even after calling the destructors in the loop. It would be better to call delete[] reinterpret_cast<char*>(data) to avoid undefined behavior. The destructors of type T must be called before freeing the memory.

Delete vs operator delete (and void pointer)

delete ptr will do overload resolution for operator delete, so it may not call the global ::operator delete

But otherwise, yes. The delete operator calls the relevant destructor, if any, and then calls operator delete.

About delete, delete[], operator delete(), etc [duplicate]

It all depends on the implementation.

Most run-times will indeed store the memory size just before the returned memory ((BYTE *)p-sizeof(size_t)) but there are other alternatives. In my own memory manager (yes, I write this kind of stuff), I have a more complex data structure (using pointers to linked lists, checksums, ...) before the returned memory. It is actually up to the memory manager to decide where to store this information.

Besides the size of the allocated memory, new[] will also store the number of instances so it knows how many destructors to call. This is normally beyond the scope of the memory manager, and is normally handled by the C++ runtime/compiler itself. But again, where this number of instances is stored depends on the compiler, although in practice I would expect this to be stored just before the returned memory (and just after any data stored by the memory manager.

EDIT:
The following small utility shows the memory layout before the allocated memory:

#include <iostream>

typedef unsigned char Byte;

class X
{
public:
X() : m_value(1) {}
~X() {m_value = 0;}
private:
int m_value;
};

void print(Byte *p,int offset)
{
printf ("Value at %d: 0x%x (%d)\n", offset, p[offset], p[offset]);
}

void main()
{
X *x = new X[10];

std::cout << "Address of x: " << x << std::endl;
std::cout << "sizeof(X) : " << sizeof(X) << std::endl;

Byte *p = (Byte *)x;
print(p,-1);
print(p,-2);
print(p,-3);
print(p,-4);
print(p,-5);
print(p,-6);
print(p,-7);
print(p,-8);
print(p,-9);
print(p,-10);

X *y = new X;
std::cout << "Address of y: " << y << std::endl;

p = (Byte *)y;
print(p,-1);
print(p,-2);
print(p,-3);
print(p,-4);
print(p,-5);
print(p,-6);
print(p,-7);
print(p,-8);
print(p,-9);
print(p,-10);
}

Running this gives the following output (on Visual Studio 2005):

Address of x: 00481DE4
sizeof(X) : 4
Value at -1: 0x0 (0)
Value at -2: 0x0 (0)
Value at -3: 0x0 (0)
Value at -4: 0xa (10)
Value at -5: 0xc (12)
Value at -6: 0x0 (0)
Value at -7: 0x2f (47)
Value at -8: 0x8 (8)
Value at -9: 0x2f (47)
Value at -10: 0x98 (152)
Address of y: 00481E70
Value at -1: 0xc (12)
Value at -2: 0x0 (0)
Value at -3: 0x2f (47)
Value at -4: 0x8 (8)
Value at -5: 0x2a (42)
Value at -6: 0x98 (152)
Value at -7: 0xf8 (248)
Value at -8: 0xb0 (176)
Value at -9: 0x0 (0)
Value at -10: 0x48 (72)

You can clearly see that in the first case (the new[]'d array), that there are 4 bytes used to indicate the number of elements (0,0,0,10 which makes together the value 10).

In the second case, these bytes are omitted and we see the same pattern (12,0,47,8) as in the first case. I don't know exactly where Visual C++ stores the number of allocated bytes, but it proves that the number of elements is indeed stored before the returned pointer (in Visual Studio 2005).



Related Topics



Leave a reply



Submit