Reputation: 2472
If Allocator
conforms to the standard library allocator interface, is it safe to call std::allocator_traits<Allocator>::deallocate
with a null pointer? I know it is when Allocator
is std::allocator
(because it ultimately defers to delete
) but what if Allocator
is a client provided class? Do I have to do an explicit check? cppreference.com
's article on the Allocator concept doesn't list any such guarantees so I think the answer is "yes" but I wanted to be sure.
To give a bit of motivation for the question, I'm imagining a use case where a variable p
is supposed to hold a pointer to the buffer (and is initially set to nullptr
), but for some reason the buffer was never allocated in the first place so p
remains a null pointer.
Upvotes: 4
Views: 605
Reputation: 153955
First off, std::allocator<T>::deallocate(T* p, std::size_t)
does not call delete p
. Instead it calls operator delete(p)
according to 23.10.9.1 [allocator.members] paragraph 7. Instead, the requirement in paragraph 5 of the same paragraph states that p
shall have been obtained from std::allocator<T>::allocate()
. This function cannot return a null pointer, i.e., std::allocator<T>::deallocate()
does not accept null points. It would be surprising if the allocator concept allows passing null pointers as std::allocator<T>
wouldn't model that concept.
The allocator concept in Table 31 likewise requires that the argument to a.deallocate(p)
was obtained from a.allocate()
. Since the specification of a.allocate(n)
always returns enough memory for n
objects (the only failure indication is via an exception) it follows that a.deallocate()
is not expected to cope with a null pointer.
The question was about allocator_traits<...>::deallocate()
. However, according to 23.10.8.2 [allocator.traits.members] paragraph 3 this function merely delegates to the deallocate()
function of the allocator. That is, a null pointer is not a valid argument there, either.
Upvotes: 6