c++ - 调用析构函数方法比较

标签 c++ malloc destructor new-operator placement-new

我只是想知道这三种调用析构函数的方法是否有任何显着/严重的区别。考虑以下代码。请同时考虑 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;
}

请在回复时具体说明您正在回答哪个案例:案例 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]);
}

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


相关主题:Destructor not called after destroying object placement-new'ed

最佳答案

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

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

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

上次测试中出现运行时错误是因为您试图删除 数组中索引1 处的对象;指向该元素的指针最初不是通过调用 new 获得的。在第一个示例中,它仅“有效”(其中“有效”的真正意思是“行为未定义,但它似乎仍能正常运行”)因为所有三个指针都指向独立的堆分配。

关于c++ - 调用析构函数方法比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4426303/

相关文章:

c++ - Boost Graph Library : How to use depth_first_visit, ColorMap 问题

c - 如何正确地将内存分配给存储在结构中的动态整数数组?

c++析构函数调用删除运算符?

c - 如何查询 pthread 以查看它是否仍在运行?

c++ - 构建字符串 vector 时是否有拷贝?

c++ - 如何将智能指针与 Allegro 位图一起使用?

c++ - 在 Python-C++-C-Fortran 2003 程序中链接英特尔的 MKL

c - 将局部指针变量的地址返回给 main() 函数

c - 使用指针数组时出现段错误

c++ - 调用可以在 C++ 中抛出异常的函数的析构函数