免责声明:我知道不应该使用unique_ptr,但为了便于理解,我想知道这里发生了什么。谢谢!
考虑这个功能:
void foo(int* a) {
unique_ptr<int> pointer_in_function(a);
}
这个主要功能:
int main(void) {
int* myInt = new int(5);
unique_ptr<int> pointer_in_main(myInt);
foo(myInt);
cout << *pointer_in_main << endl;
cout << *pointer_in_main << endl;
cin.get();
return 0;
}
我始终从第一个cout得到正确答案。第二个是未定义的。程序有时在退出时崩溃并出现严重错误,但并非总是如此。
我不明白为什么第一个cout始终给出正确的答案。当pointer_in_function超出范围时,是否已删除myInt指向的整数?谢谢你的帮助!
编辑:顺便说一下,为了确定,我是否正确地假设调用foo应该删除我的整数因为pointer_in_function超出范围?
答案 0 :(得分:5)
我不明白为什么第一个cout一直给出正确的答案。
大多数实现在删除后都没有清除内存或将其返回给操作系统,所以如果你在删除后快速检查内存,那么它没有被覆盖的可能性会更高。
这是未定义行为的有效后果之一。它可能在您的特定实现上100%可预测,但在其他实现时不需要表现相同。
答案 1 :(得分:1)
使用构造函数/析构函数或删除进行(纯粹的)实验不是一个好方法。如果你有一个没有损坏的对象,它就意味着没有调用delete
运算符(因为它对内存数据的影响是不确定的,实际上许多内存管理器实现都没有改变立即发布的内存内容)。相反,创建一个具有显式构造函数的类,并使用析构函数报告其调用,并使用它代替int
。作为析构函数调用预先删除对象(并且由于您的代码不使用测试对象的堆栈或静态分配,析构函数调用总是暗示删除),您可以使用析构函数调用来跟踪删除。类似的东西:
#include <iostream>
class MyObj {
int value;
MyObj(int v) : value(v) {std::cerr << "MyObj ctor called"<<std::endl;}
~MyObj() {std::cerr << "MyObj dtor called"<<std::endl;}
};
.....
int main (int argc, char **argv) {
MyObj* myInt = new MyObj(5);
....
}