Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allocating zero objects with std::allocator::allocate(0) in C++

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?

like image 596
Olle Lindeberg Avatar asked Dec 04 '18 10:12

Olle Lindeberg


2 Answers

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."

like image 166
Werner Henze Avatar answered Nov 01 '22 08:11

Werner Henze


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.

like image 44
Bathsheba Avatar answered Nov 01 '22 09:11

Bathsheba