Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of destruction of elements of an std::vector [duplicate]

Possible Duplicate:
STL containers element destruction order

Is there a guarantee the the elements of an std::vector would be destroyed from last to first?

like image 825
shoosh Avatar asked May 29 '11 17:05

shoosh


3 Answers

2003:5.3.5/6 says about delete[]:

The delete-expression will invoke the destructor (if any) for the object or the elements of the array being deleted. In the case of an array, the elements will be destroyed in order of decreasing address (that is, in reverse order of the completion of their constructor; see 12.6.2).

So if your std::vector object's allocator uses delete[] then, yes, it is bound to destroy elements in reverse order.

However, there is no guarantee that your std::vector will work this way (and, in fact, it most likely does not), and I can't find any citations specific to the container.

Really, I think it's all down to your allocator and 2003:20.1.5 (which lists the requirements placed upon allocators) doesn't appear to say anything about it.

like image 83
Lightness Races in Orbit Avatar answered Oct 11 '22 11:10

Lightness Races in Orbit


No, there are guarantees for arrays, where all elements are constructed is order and destroyed in the reverse order. This is somewhat consistent with how global objects are handled.

Container members, on the other hand, can be constructed and destroyed in any order using for example insert and erase member functions. To be somewhat consistent and destroy the elements in the reverse order of construction, this would require the containers to keep some kind of log over these changes. Obviously this would be expensive!

The best bet is that the container destructor calls clear(), which is defined as erase(begin(), end()), but I cannot find any requirements for that either. The standard only says "linear complexity" in table 65.

like image 39
Bo Persson Avatar answered Oct 11 '22 10:10

Bo Persson


They standard guarantees this for a raw array, but I can't find anything that would guarantee it for containers.

From [expr.delete] (new wording for C++0x):

If the value of the operand of the delete-expression is not a null pointer value, the delete-expression will invoke the destructor (if any) for the object or the elements of the array being deleted. In the case of an array, the elements will be destroyed in order of decreasing address (that is, in reverse order of the completion of their constructor; see 12.6.2).

std::vector (and in fact, all containers in the standard library, possibly excluding std::array) do not use delete[] to destroy the elements (they use allocator_traits<allocator_type>::destroy on each element individually), so the above guarantee doesn't apply. And I can find no restrictions on std::vector in particular or containers in general, about the order of deletion. For some containers, such a guarantee would be very expensive (e.g. std::forward_list can't iterate the elements in reverse to delete them, and std::map doesn't remember the order in which pairs were added).

From [container.requirements.general] (C++0x wording):

For the components affected by this subclause that declare an allocator_type, objects stored in these components shall be constructed using the allocator_traits::construct function and destroyed using the allocator_traits::destroy function (20.6.8.2).

like image 5
Ben Voigt Avatar answered Oct 11 '22 11:10

Ben Voigt