Alessandro Power
Alessandro Power

Reputation: 2472

Calling allocator_traits::deallocate on a null pointer

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

Answers (1)

Dietmar K&#252;hl
Dietmar K&#252;hl

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

Related Questions