c++ - 在自动对象上调用 delete

标签 c++

考虑以下 C++ 代码:

class test
{
public:
    int val;

    test():val(0){}
    ~test()
    {
        cout << "Destructor called\n";
    }
};

int main()
{
    test obj;
    test *ptr = &obj;
    delete ptr;

    cout << obj.val << endl;

    return 0;
}

我知道 delete 应该只在动态分配的对象上调用,但是现在 obj 会发生什么?

好的,我知道我们不应该做这样的事情,现在如果我正在编写以下智能指针的实现,我如何才能确保这样的事情不会发生。

class smart_ptr
{
public:
    int *ref;
    int *cnt;

    smart_ptr(int *ptr)
    {
        ref = ptr;
        cnt = new int(1);
    }

    smart_ptr& operator=(smart_ptr &smptr)
    {
        if(this != &smptr)
        {
            //  House keeping
            (*cnt)--;
            if(*cnt == 0)
            {
                delete ref;
                delete cnt;
                ref = 0;
                cnt = 0;
            }

            //  Now update    
            ref = smptr.ref;
            cnt = smptr.cnt;
            (*cnt)++;
        }
        return *this;
    }

    ~smart_ptr()
    {
        (*cnt)--;
        if(*cnt == 0)
        {
            delete ref;
            delete cnt;
            ref = 0;
            cnt = 0;
        }
    }
};

最佳答案

您在帖子中提出了两个截然不同的问题。我会分开回答。

but what would happen to obj now ?

您的程序的行为未定义。 C++ 标准对 obj 现在发生的事情没有任何评论。事实上,该标准也没有评论您的程序在错误之前做了什么。它只是未定义

也许您的编译器供应商 promise 会发生什么,也许您可​​以检查程序集并预测会发生什么,但是 C++ 本身并没有定义会发生什么。

实际上1,您可能会收到来自标准库的警告消息,或者您会收到段错误,或者两者兼而有之。

1:假设您在 Windows 或带有 MMU 的类 UNIX 系统中运行。其他规则适用于其他编译器和操作系统。


how can i make sure that [deleteing a stack variable] doesn't happen.

永远不要用堆栈变量的地址初始化smart_ptr。一种方法是记录 smart_ptr 的接口(interface)。另一种方法是重新定义接口(interface),使用户永远不会传递指向 smart_ptr 的指针;让 smart_ptr 负责调用 new

关于c++ - 在自动对象上调用 delete,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13478150/

相关文章:

c++ - MSVC C++ 调用 GFortran 子例程

C++ 文件在第一行后停止读取

c++ - Qt闯关游戏

c++ - tr1::mem_fn 和具有默认参数的成员

c++ - 如何改变 boost::variant operator < 的行为

c++ - 如何在 BCB XE 中将十六进制字符串编码为整数

c++ - 如何避免用户输入错误的信息?

c++ - 删除动态二维数组不起作用

c++ - 如何创建模板依赖成员类型

c++ - 构造 std::tuple 类型的索引数组