Search code examples
c++stdallocator

C++ does it lead to double free when destroy element in allocator<string>?


C++ Allocator. I know that String will allocate a block buffer with new at inner implement, and free it(call delete[]) within Destructor.

My question is that whether it will be free double when use allocator<string>?

  1. first free at string destructor.
  2. second deallocate buffer points to string has been free.

Additionally, whether does the buffer address of string and allocate(n) have same region?

#include <iostream>
#include <memory>
#include <string>

using namespace std;

int main(int argc, char **argv)
{
    const int cnt = 10;
    allocator<string> alloc;
    auto p = alloc.allocate(cnt);

    alloc.construct(p);
    for (int i = 0; i < cnt; ++i)
    {
        cout << p+i << endl; // print buffer address
    }

    alloc.destroy(p); // will it free buffer of string?

    alloc.deallocate(p, cnt); // will it free buffer of string again?

    return 0;
}

Solution

  • When you write something like this:

    Foo *foo = new Foo();
    

    two things happen:

    1. Some heap space is allocated for the Foo object.
    2. The Foo() constructor is invoked, with this pointing to the newly-allocated space.

    Later, you delete the Foo object:

    delete foo;
    

    and two more things happen:

    1. The destructor ~Foo() is invoked.
    2. The memory allocated for the Foo instance is released back to the heap.

    The std::allocator class just lets you perform each of these four steps manually.

    If you have an allocator<string> alloc and you call alloc.allocate and then alloc.construct, that's just the same as doing new string(). And when you call alloc.destroy and then alloc.deallocate, that's just the same as deleting the string pointer.

    So no, there won't be any extra frees going on. The call to destroy causes the string to release whatever memory it allocated for its buffer, and then the call to deallocate releases the memory that was used for the string object itself.

    I didn't completely understand your question about the region. The memory allocated to store the string instance, and the memory that the string allocates for its buffer, are unrelated.