调用析构函数方法比较

Naw*_*waz 0 c++ malloc destructor placement-new new-operator

我只是想知道这三种调用析构函数的方法是否有任何重大/严重的区别.请考虑以下代码.还请考虑提到的两个案例main().

class Sample 
{
public:
    ~Sample()
    {
        cout << "destructor called" << endl;
    }
    void destroyApproach1() { this->~Sample(); }
    void destroyApproach2() { delete this; }
};

void destroyApproach3(Sample *_this)
{
    delete _this;
}

void TestUsingNew()
{
    Sample *pSample[] = { new Sample(), new Sample(),new Sample()};
    pSample[0]->destroyApproach1();
    pSample[1]->destroyApproach2();
    destroyApproach3(pSample[2]);
}
void TestUsingPlacementNew()
{
    void *buf1 = std::malloc(sizeof(Sample));
    void *buf2 = std::malloc(sizeof(Sample));
    void *buf3 = std::malloc(sizeof(Sample));
    Sample *pSample[3] = { new (buf1) Sample(), new (buf2) Sample(), new (buf3) Sample()};
    pSample[0]->destroyApproach1();
    pSample[1]->destroyApproach2();
    destroyApproach3(pSample[2]);
}
int main() 
{ 
    //Case 1 : when using new
    TestUsingNew();

    //Case 2 : when using placement new
    TestUsingPlacementNew();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在回复您回答的案例时请具体说明:案例1或案例2,或两者兼而有之!


此外,我试图以TestUsingPlacementNew()这种方式编写,但它正在抛出运行时异常(MSVC++ 2008).我不明白为什么:

void TestUsingPlacementNew()
{
    const int size = sizeof(Sample);
    char *buffer = (char*)std::malloc( size * 3);
    Sample *pSample[] = { new (buffer) Sample(), new (&buffer[size]) Sample(),new  (&buffer[2*size]) Sample()};
    pSample[0]->destroyApproach1();
    pSample[1]->destroyApproach2();
    destroyApproach3(pSample[2]);
}
Run Code Online (Sandbox Code Playgroud)

也许,内存填充和/或对齐可能是原因?


相关主题:销毁对象放置后未调用的析构函数

Jam*_*lis 5

是的,这些方法之间存在巨大差异:

  • destroyApproach1,你只调用对象的析构函数; 你实际上没有释放它占用的内存.

  • destroyApproach2destroyApproach3你调用该对象的析构函数你释放该对象所占用的内存(使用delete表达式).在第一个TestUsingPlacementNew测试中,这两个都是错误的,因为对象占用的内存最初是通过调用而malloc不是通过调用来分配的new.

上次测试中发生运行时错误的原因是您尝试在数组delete中的索引处对象1; 最初没有从调用中获取指向该元素的指针new.在第一个例子中,它只"工作"(其中"工作"实际上意味着"行为未定义,但它似乎仍能正常运行),因为所有三个指针都是独立的堆分配.