Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Usage of std::destroy_at() in c++17?

Tags:

c++

c++17

I have simple code snippet which is trying to free the memory using std::destroy_at():

#include <iostream>
#include <memory>

using namespace std;

class base
{
public:
  ~base()
  {
    cout << "des" << endl;
  }
};
int main()
{
  {
    base* b1 = new base();
    std::destroy_at(b1); // destructor is executed for b1 object (but memory is not freed for b1)
  }
return 0;
}

Can someone guide me how to use destroy_at() for freeing the memory? Same behavior observed for primitive data types also. Using VS2017 compiler latest.

like image 399
Mahendra Avatar asked Sep 26 '18 03:09

Mahendra


1 Answers

std::destroy_at() is not meant to deallocate memory according to [specialized.destroy]p1 it is meant to call the destructor of the object:

template<class T>
void destroy_at(T* location);
1. Effects: Equivalent to:

location->~T();

The cppreference entry gives an example of why this might be needed. In this case we have used placement new into a buffer and there is no need to free the memory:

struct Tracer {
    int value;
    ~Tracer() { std::cout << value << " destructed\n"; }
};

int main()
{
    alignas(Tracer) unsigned char buffer[sizeof(Tracer) * 8];

    for (int i = 0; i < 8; ++i)
        new(buffer + sizeof(Tracer) * i) Tracer{i}; //manually construct objects

    auto ptr = std::launder(reinterpret_cast<Tracer*>(buffer));

    for (int i = 0; i < 8; ++i)
        std::destroy_at(ptr + i);
}

The proposal that brought this in Extending memory management tools says:

It is common for both the standard library and user libraries to manage memory without the use of standard-compliant allocators. They may use internal buffers (like optional) or use an allocator model that does not manage object lifetime [bde] [sgi] [eastl] [bitsquid]. Such alternative allocator models are common in efficiency-critical applications.
....

like image 188
Shafik Yaghmour Avatar answered Nov 20 '22 03:11

Shafik Yaghmour