6

new int[0] is permitted in C++ but is std::allocator<int>().allocate(0) well defined? More general, must all Allocators accept 0 as a parameter to allocate?

Edit: After reading the answers I tested Visual Studio's std::allocator: allocate(0) gives nullptr

deallocate(nullptr, anything) is a nop.

So using nullptr is a good suggestion, but the standard do not demand that deallocate(nullptr, 0) is a nop, see C++ allocator::deallocate(NULL,1) allowed?

plasmacel
  • 8,183
  • 7
  • 53
  • 101

2 Answers2

4

Table 34 β€” Cpp17Allocator requirements
Memory is allocated for n objects of type T but objects are not constructed. allocate may throw an appropriate exception.174 [Note: If n == 0, the return value is unspecified. β€”end note]

I would read that as "The allocator shall/should handle n == 0, not throw and return a value that might be a valid pointer or be nullptr."

plasmacel
  • 8,183
  • 7
  • 53
  • 101
Werner Henze
  • 16,404
  • 12
  • 44
  • 69
  • I suspect that's related to the implementation of (if not directly inherited from) C's [**7.22.3 Memory management functions**](https://port70.net/~nsz/c/c11/n1570.html#7.22.3): "If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object." – Andrew Henle Dec 04 '18 at 10:22
  • @AndrewHenle [yes but it is not allowed to return nullptr like C is](https://twitter.com/shafikyaghmour/status/1024212665554558976) – Shafik Yaghmour Dec 04 '18 at 14:06
3

Indeed new int[0] is well-defined. Note that you are required to call delete[] on the returned pointer, and the behavior on dereferencing the pointer is undefined.

Similar rules apply to std::allocator().allocate(0): you can't dereference the returned pointer, and you need to clean up memory in the normal way by calling std::allocator::deallocate.

An allocator is allowed to throw a std::bad_alloc exception; you could deal with the 0 parameter case by doing that, without contravening any requirements laid down by the standard. Returning nullptr is an alternative.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483