考虑以下 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 [
delete
ing 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/