usual me
usual me

Reputation: 8778

Destroy vs Deallocate

In chapter 11 of Accelerated C++, the authors present a Vector class emulating the behaviour of std::vector using arrays. They use the allocator class to handle memory management. The role of the uncreate function is to destroy each element of the array and deallocate the space allocated for the array:

template <class T> void Vec<T>::uncreate() {
  if (data) {

  // destroy (in reverse order) the elements that were constructed 
  iterator it = avail;
  while (it != data)
    alloc.destroy(--it);

  // return all the space that was allocated
  alloc.deallocate(data, limit - data); 
  }

  // reset pointers to indicate that the Vec is empty again 
  data = limit = avail = 0;
}

Obviously we need to deallocate allocated space. But it's unclear to me why we need to destroy individual elements as well. What would happen if we only deallocated memory without destroying individual elements?

Upvotes: 11

Views: 3305

Answers (2)

jrok
jrok

Reputation: 55395

The reason is that it'd might get you in trouble. The paragraph 4 from chapter 3.8 (Object lifetime) of C++standard explains why (emphasis mine):

A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.

It means it's fine to do it on memory that's occupied by objects with trivial destructor(*) or objects that don't have one at all (such as ints and the like). But when the memory contains objects of a class that needs to do some work in the destructor (like closing network connections or files, flushing buffers, releasing memory), you'll leak resources (and formaly by the standard, invoke undefined behaviour).

(*) A destructor is trivial if it's compiler generated, is not virtual, and all the non-static members and direct base classes of the class it is member of have trivial destructors.

Upvotes: 14

dunc123
dunc123

Reputation: 2713

Destroying the individual elements ensures that their destructors are called and therefore they have a chance to free any resources they own. Simply deallocating the memory would not call the destructor of the object placed in that memory.

Upvotes: 10

Related Questions