首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >位置删除函数永远不会在异常时调用

位置删除函数永远不会在异常时调用
EN

Stack Overflow用户
提问于 2018-11-30 16:49:29
回答 4查看 105关注 0票数 0

placement delete用于在placement new中发生异常时释放内存。所以我做了一个测试:

代码语言:javascript
运行
复制
#include <iostream>
#include <new>
using namespace std;
class A {
public:
    A(){
        cout << "constructor" << endl;
        throw 1;
    }
};

void* operator new(size_t size, int i){
    cout << "in placement new" << endl;
    return ::operator new(size);
}

void operator delete(void *ptr, int i){
    cout << "in placement delete" << endl;
    ::operator delete(ptr);
}

int main(){
    int o = 9;
    A* a = new(o) A;
}

位置删除函数从来没有被调用过,它只是退出了。为什么?

EN

回答 4

Stack Overflow用户

发布于 2018-11-30 17:11:47

你的程序抛出一个未捕获的异常。这意味着调用了std::terminate

在这种情况下,可能会有堆栈展开,也可能没有堆栈展开(这是由实现定义的)。您的实现显然决定在不展开堆栈的情况下调用std::terminate

operator delete的调用实际上是stack unwinding的一部分,尽管这里没有涉及堆栈,但这有点用词不当。

要查看正在调用的函数,请将代码更改为:

代码语言:javascript
运行
复制
try
{
    A* a = new(o) A;
}
catch(...) {}

票数 5
EN

Stack Overflow用户

发布于 2018-11-30 17:12:41

这是因为您没有捕捉到异常,所以不会调用用于删除的相关代码。只需将其封装在try/catch块中:

代码语言:javascript
运行
复制
try 
{
    int o = 9;
    A* a = new(o) A;
} 
catch (int i) { }

请记住,您必须有效地捕获构造函数引发的异常,而不仅仅是任何异常。

票数 2
EN

Stack Overflow用户

发布于 2018-11-30 17:15:21

如果您正确处理异常,则会显示placement operator delete finction is being called

如果您不处理异常,则允许实现在throw时立即终止您的程序,而无需展开堆栈,例如,no destructors are called

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53554133

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档