What does the following code do?
obj *x = new obj[100];
delete x; // Note the omission of []
Does it delete only the first element in the array?
Consider this example: int *ptr; int arr[5]; // store the address of the first // element of arr in ptr ptr = arr; Here, ptr is a pointer variable while arr is an int array.
When we allocate memory to a variable, pointer points to the address of the variable. Unary operator ( * ) is used to declare a variable and it returns the address of the allocated memory. Pointers to an array points the address of memory block of an array variable.
Arrays in C are basically just pointers that reserve consecutive blocks of memory. So in essence arrays always act like pointers. Arrays in C are arrays.
Can we create an array of pointers in C? Yes, we can.
The code above exhibits undefined behavior: it should be
delete[] x;
because the allocation was done with new[]
.
When you use the correct operator, the entire array pointed to by the pointer gets deleted:
obj *x = new obj[100];
delete[] x; // The entire array gets deleted
Even though it is undefined behavior, you should probably take note of the most likely result (for the sake of debugging such issues).
When you create an array via new Object[100]
, the memory is first allocated. The default behavior (provided there were no overrides to the default allocator) is to simply call malloc(100 * sizeof(Object))
. After that, the constructor for Object
needs to be called on each Object
-sized region. This is an important detail: the memory is allocated once, but the constructor is called in 100 locations.
When a block is allocated via malloc
, it cannot be freed in pieces. Only a call to free(block)
will release that memory. The C++ keyword delete
internally calls free
if the keyword new
calls malloc
. So, the proper way to delete an array is to call delete [] array
. So, what happens if you call delete array
? The likely answer is that the memory will be freed (all of it, not just the first element), but only one destructor will be called: the first element's destructor.
Obviously, there are lots of facts to consider. new
and delete
are not necessarily bound to malloc
and free
. They may use system calls unique to a specific architecture or operating system. (Windows, in particular, has a whole set of heap management functions outside of malloc
and free
in its C API.) I simply demonstrated the example with malloc
and free
because that is what I have seen the most often when stepping through code. Visual Studio, for example, lets you step into new
calls and actually see the new
function code. (That's another important detail. new
and delete
are simply function calls, which you can even override in many cases.)
You can demonstrate this concept with this little program. Simply create an Object
class that outputs something during the constructor and outputs something else during the destructor.
int main(int argc, char** argv)
{
Object* o = new Object[4];
delete o;
return 0;
}
I ran it, and sure enough: the constructor was called 4 times, and the destructor was called once.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With