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
Best Practices For Circular Shift (Rotate) Operations in C++
How Do Malloc() and Free() Work
#Pragma Once VS Include Guards
What's the Correct Way to Use Printf to Print a Size_T
How to Implement Classic Sorting Algorithms in Modern C++
What Is the Proper Declaration of Main in C++
What Is "Rvalue Reference For *This"
What Are the Evaluation Order Guarantees Introduced by C++17
If You Shouldn't Throw Exceptions in a Destructor, How to Handle Errors in It
What Is External Linkage and Internal Linkage
Is There a Performance Difference Between I++ and ++I in C++
How to Create a Contiguous 2D Array in C++
Fastest Way to Check If a File Exists Using Standard C++/C++11,14,17/C