tutorial

All posts tagged tutorial

Ok,

So getting back into C++ programming, I’ve been allocating plenty of dynamic memory (using new  and new[] ) .  However, I’ve only been using delete , never delete[] .  If fact, I’ll be honest, I forgot about delete[] , but that’s OK, I didn’t need the [] form anyway.  Why you ask?

Take this example:

Now, almost every example you see online will actually have delete[] buf; , this is correct, but unnecessary.  Why?  The only difference between delete and delete[] is item deconstruction.

When you call delete, all the memory you allocated with new[] is still erased. The problem is, only the first element (the one being directly pointed to) is deconstructed. None of the other members of your array are deconstructed. In my example this is OK, because the array was an array of “char”s, you can’t deconstruct a char in C++, it’s not an object.

 

When is delete[] useful?

When you allocate an array of objects that themselves allocate more memory. delete[]  makes sure that each entry in the allocated array is properly deconstructed. Example:

 

Can I just call delete[] all the time?

Sure, well, almost.   delete[]  works on a specific type of pointer.  When you call myclass * myptr = new myclass[5] , you are telling the system to reserve you sizeof(myclass)*5  bytes of memory.  This size is all that is stored in the memory allocator.  When you call delete[] myptr; , the memory allocator goes through the following process:

  1. How much memory was reserved starting at the address stored in myptr (answer: sizeof(myclass) * 5);
  2. Start at offset = 0.
  3. Call the myclass.deconstructor at the address myptr + offset.
  4. Increase offset by sizeof(myclass)
  5. If offset < total allocated memory, goto 3.  Else, continue;
  6. Delete/Free all memory reserved (sizeof(myclasS) * 5 bytes) starting at address storef in myptr;.

However, if you tried to call delete[] (void *) myptr;  all calls to sizeof(myclass) above will be replaced with sizeof(void), which returns no size (no object can be of type void). Therefore, none of the objects in the array will be deconstructed.  Calling delete[] (void *)ptr;  is the same as calling delete (void *)ptr; .

Similarly, if you recast the pointer to a different type, delete[] will not know the proper size of each object, and any attempts to deconstruct those “objects” will most likely result in errors/exceptions.  Example:

Of course, casting pointers in C++ is always dangerous.  The compiler and system do not keep track of allocated memory by type, only size.  Therefore, you should always be careful when having to cast a pointer.

Note: There are acceptable times to cast a pointer (when reading in bytes that are actually multi-byte values, say casting an int* as a char*), but often times, this can also be handled with Unions.

Anyway, that’s my “quick” overview of the delete and delete[] operations in C++.