释放从新位置分配的内存

Raj*_*hta 2 c++ memory-management placement-new

考虑以下代码,

#include "iostream"
#include "conio.h"

using namespace std;

class sample
{
      private:
              int i;
      public:
             sample(int ii=0) : i(ii){                         
                   cout<<"Constructing Object"<<endl; 
                   }

             ~sample() { cout<<"Destructing Object"<<endl; }

             void* operator new(size_t nSize, void* loc){
                   cout <<"Inside new"<<endl;
                   cout <<loc<<endl;
                   return loc;
                   }

             void operator delete(void* ptr){
                  cout <<"Inside delete"<<endl;
                  free(ptr);
                  }
};


int main()
{
    int intArr[2];
    sample* samplePtr = new(intArr) sample(5);
    cout <<samplePtr<<endl;

    delete samplePtr;  
//    samplePtr->sample::~sample();
    getch();
}
Run Code Online (Sandbox Code Playgroud)

输出:

Inside New
0x22ff38
Constructing Object
0x22ff38
Destructing Object
Inside Delete
Run Code Online (Sandbox Code Playgroud)

在这里,我动态请求已经在堆栈上分配的内存.我读过,一旦完成,我需要明确地调用析构函数.但是当我尝试为堆栈上分配的内存调用delete时,我会调用析构函数.这是否意味着在调用析构函数后释放堆栈上的内存?

如果我动态请求早先在堆上分配的内存,那么我需要调用delete,但是实际上是否删除堆栈上的空闲内存?

And*_*zos 14

普通的new运算符有两件事:

  1. 调用动态内存管理器来获取大块内存
  2. 调用构造函数

普通删除操作符执行相反的操作

  1. 调用析构函数
  2. 调用动态内存管理器来释放大量内存

Placement new只做一步:

  1. 调用构造函数

所以"放置删除"应该只做一步:

  1. 调用析构函数

如上所述,您不应在放置新内容后调用正常删除.(原因是这样做会要求动态内存管理器删除它未分配的块,导致未定义的行为)

这条线错了:

delete samplePtr;  // WRONG
Run Code Online (Sandbox Code Playgroud)

您需要执行"placement delete",这只是一个原始调用descructor:

samplePtr->~sample(); // CORRECT
Run Code Online (Sandbox Code Playgroud)