MaksymB
MaksymB

Reputation: 1307

C++ memory allocators and polymorphic types

Are memory allocators supposed to be used with polymorphic types? For example, is the code below correct?

class A { ... };
class B { ... };
class C : public A, public B { ... };

std::allocator<C> alloc_c;
auto p_c = alloc_c.allocate(1);

// CASE A: pointer to A and to C point to the same memory address
std::allocator<A> alloc_a(alloc_c);
alloc_a.deallocate((A*)p_c, 1);

// CASE B: pointer to B and to C point to the different memory addresses
std::allocator<B> alloc_b(alloc_c);
alloc_b.deallocate((B*)p_c, 1);

Of course, it's either case A or case B, not both.

Upvotes: 2

Views: 272

Answers (1)

Igor Tandetnik
Igor Tandetnik

Reputation: 52611

Table 28 in 17.6.3.5 defines deallocate this way:

a.deallocate(p,n): All n T objects in the area pointed to by p shall be destroyed prior to this call. n shall match the value passed to allocate to obtain this memory. Does not throw exceptions. [ Note:p shall not be singular.—end note ]

Per Table 27 right above, p is "a value of type XX::pointer, obtained by calling a1.allocate, where a1 == a" (where XX is "the type allocator_traits<X>", and X is "an Allocator class for type T"). Further, a and a1 are "values of type X&".

In other words, the standard does not envision passing to deallocate a pointer allocated by an allocator of a different type. It only specifies what happens when deallocate is given a pointer allocated by the same allocator object, or another allocator of the same type that compares equal to this allocator.

At which point, we have

1.3.24 undefined behavior

behavior for which this International Standard imposes no requirements [ Note: Undefined behavior may be expected when this International Standard omits any explicit definition of behavior...]

Upvotes: 2

Related Questions