考虑下面的代码,
#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();
}
Output:
Inside New
0x22ff38
Constructing Object
0x22ff38
Destructing Object
Inside Delete
在这里,我动态地请求已经在堆栈上分配的内存。我读到完成后我需要显式调用析构函数。但是当我尝试调用删除堆栈上分配的内存时,我会调用析构函数。这是否意味着调用析构函数后会释放堆栈上的内存?
如果我动态请求之前在堆上分配的内存,在这种情况下我需要调用delete,但delete实际上会释放堆栈上的内存吗?
普通的 new 运算符做了两件事:
- 调用动态内存管理器来获取内存块
- 调用构造函数
普通的删除操作符则相反
- 调用析构函数
- 调用动态内存管理器来释放内存块
Placement new 只做了一步:
- 调用构造函数
所以“展示位置删除”应该只执行一步:
- 调用析构函数
您不应该像您所做的那样,在放置新位置后调用普通删除。 (原因是这样做会要求动态内存管理器删除它未分配的块,从而导致未定义的行为)
这行是错误的:
delete samplePtr; // WRONG
您需要执行“放置删除”,这只是析构函数的原始调用:
samplePtr->~sample(); // CORRECT
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)