gpt4 book ai didi

c++ - 重置后尝试访问指针

转载 作者:行者123 更新时间:2023-11-30 01:47:04 26 4
gpt4 key购买 nike

调试应用程序并进行一些试验,我发现了一个非常奇怪的行为,可以使用以下代码重现:

#include <iostream>
#include <memory>

int main()
{
std::unique_ptr<int> p(new int);

*p = 10;
int& ref = *p;
int* direct_p = &(*p);

p.reset();

std::cout << *p << "\n"; // a) SIGSEGV
std::cout << ref << "\n"; // b) 0
std::cout << *direct_p << "\n"; // c) 0
return 0;
}

在我看来,所有三种变体都必须导致未定义的行为。牢记这一点,我有以下问题:

  1. 为什么 refdirect_p 仍然指向零? (不是 10)(我的意思是,int 的销毁机制对我来说似乎很奇怪,编译器在未使用的内存上重写有什么意义?)
  2. 为什么 b) 和 c) 不触发 SIGSEGV?
  3. 为什么 a) 的行为与 b) 和 c) 不同?

最佳答案

p.reset();相当于p.reset(nullptr); .所以 unique_ptr 的内部指针被设置为空。因此做 *p最终得到的结果与尝试取消引用空指针的结果相同。

另一方面,refdirect_p仍然指向该 int 以前占用的内存。试图用它们来读取内存进入未定义行为领域,所以原则上我们不能得出任何结论......

但在实践中,我们可以对一些事情做出有根据的假设和猜测。

由于该内存位置不久之前是有效的,所以当您的程序通过 ref 访问它时,它很可能仍然存在(尚未从地址空间或其他此类特定于实现的事物中取消映射)和 direct_p . C++ 不要求内存应该变得完全不可访问。因此,在这种情况下,您只是“成功地”读取了程序执行期间那个内存位置上发生的任何内容。

至于为什么值恰好为 0,有两种可能性。一个是您可以在 Debug模式下运行,该模式有目的地将已释放的内存归零。另一种可能性是,当您通过 ref 访问该内存时和 direct_p其他东西已经出于不同的目的重新使用它,最终使它具有该值(value)。你的std::cout << *p << "\n"; line 可能已经做到了这一点。

关于c++ - 重置后尝试访问指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32083611/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com