为什么这个智能指针在它的目标应该被删除时却给出了正确的结果?
Why does this smart pointer give the correct result when its target should have been deleted?
免责声明:我知道 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 始终给出正确答案。当 pointer_in_function 超出范围时,不应该删除 myInt 指向的整数吗?感谢您的帮助!
编辑:顺便说一句,为了确定,我假设调用 foo 应该删除我的整数是正确的,因为 pointer_in_function 超出范围吗?
What I do not understand is why the first cout gives the correct answer consistently.
大多数实现不会在删除后清除内存或return它回到OS,所以如果你在删除后快速检查内存,它没有被覆盖的可能性更高.
这是未定义行为的有效后果之一。它在你的 特定实现上可能是 100% 可预测的,尽管它不需要在其他实现上表现相同。
这不是用构造函数/析构函数或删除进行(足够纯粹)实验的好方法。如果你有一个未损坏的对象,它并不意味着没有调用 delete
运算符(因为它对内存数据的影响是未定义的,实际上许多内存管理器实现不会立即更改释放的内存内容) .相反,创建一个带有显式构造函数和析构函数报告其调用的 class,并用它代替 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);
....
}
免责声明:我知道 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 始终给出正确答案。当 pointer_in_function 超出范围时,不应该删除 myInt 指向的整数吗?感谢您的帮助!
编辑:顺便说一句,为了确定,我假设调用 foo 应该删除我的整数是正确的,因为 pointer_in_function 超出范围吗?
What I do not understand is why the first cout gives the correct answer consistently.
大多数实现不会在删除后清除内存或return它回到OS,所以如果你在删除后快速检查内存,它没有被覆盖的可能性更高.
这是未定义行为的有效后果之一。它在你的 特定实现上可能是 100% 可预测的,尽管它不需要在其他实现上表现相同。
这不是用构造函数/析构函数或删除进行(足够纯粹)实验的好方法。如果你有一个未损坏的对象,它并不意味着没有调用 delete
运算符(因为它对内存数据的影响是未定义的,实际上许多内存管理器实现不会立即更改释放的内存内容) .相反,创建一个带有显式构造函数和析构函数报告其调用的 class,并用它代替 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);
....
}