0

Consider some standard container which uses dynamic memory (i.e. is an AllocatorAwareContainer) and has a size and capacity of zero. For example, take a std::vector and call vec.resize(0); vec.shrink_to_fit();.

I would imagine that such container instances would contain only nullptr pointers for their logical contents and std::size_t members to track information like size. I would also imagine that their destructors would do essentially nothing, as there is no dynamic memory to be freed.

All destructors of containers, as I know, are noexcept. I.e. on throwing of an exception during destruction they should call std::terminate. It is possible in case of Allocator::deallocate() throw exception.

Can I be sure containers in the state, described above, never call std::terminate on destruction?

Tomilov Anatoliy
  • 15,657
  • 10
  • 64
  • 169
  • Sorry, can you reword your first two paragraphs. I am not able to understand the requirement from it. – Arunmu Jan 08 '16 at 10:39
  • @Arunmu Not sure. I use google translate, and that's all I can out of him. – Tomilov Anatoliy Jan 08 '16 at 10:43
  • @Arunmu If the question is really poor formulated you just can vote to close it. – Tomilov Anatoliy Jan 08 '16 at 10:45
  • I really do not want to do that. Can you instead try to provide another code example with little comments on it. If thats more clear then I can edit the question. – Arunmu Jan 08 '16 at 10:49
  • 1
    I rephrased the opening paragraphs, feel free to rollback if you don't like the changes. – TartanLlama Jan 08 '16 at 10:53
  • Ok, so is the question about deleting null pointer in containers destructor by the allocator ? In C++ delete on a null pointer is NOT an undefined behaviour. – Arunmu Jan 08 '16 at 11:00
  • @Arunmu Roughly speaking, this is a question about: is it possible that `}` call `std::terminate` in statement `{ std::container c = ...; c.clear(); c.shrink_to_fit(); }`? – Tomilov Anatoliy Jan 08 '16 at 11:05
  • Example was really irrelevant. – Tomilov Anatoliy Jan 08 '16 at 11:10
  • Yes, in case the container stores elements that can throw while copying (in case move is not noexcept) or while moving (in case of noexcept). The container might give a basic or strong guarantee in such cases, but if you do not catch the exception, it will call std terminate. – Arunmu Jan 08 '16 at 11:19
  • My above comment was for std::vector – Arunmu Jan 08 '16 at 11:19
  • `shrink_to_fit` is only an advise. The container is allowed to keep some buffer allocated. – Ilya Popov Jan 08 '16 at 11:24
  • @IlyaPopov yeah, but then thats implementation defined. – Arunmu Jan 08 '16 at 11:27
  • What would such guarantee be useful for? The program may be terminated for million and one other reasons (power failure, out-of-memory, external signal, etc.) at any point anyway. – Jan Hudec Jan 08 '16 at 12:28

1 Answers1

4

It is possible in case of Allocator::deallocate() throw exception.

No, it's not. The requirements for Allocator forbid deallocate to throw. It's not a formal noexcept specifier, but C++14 Table 28 Allocator requirements says:

a.deallocate(p, n) [...] Does not throw exceptions.

So if your allocator throws on deallocation, that's a violation of the required contract and all bets are off anyway.

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157