【问题标题】:Catching a dangling pointer [duplicate]捕捉悬空指针[重复]
【发布时间】:2016-09-19 18:40:35
【问题描述】:

我编写了以下代码,输出45:

#include <iostream>

int main() 
{
    int *p;
    {
        int n = 45;
        p = &n;
    }
    std::cout << *p;
}

因为n 的生命周期在我预期此代码会发出错误或警告的范围内结束。使用 GCC 6.1.0 和 Clang 3.8.0 以及 libubsan sanitizer 我没有得到任何提示。

g++ -Wall -Wextra -pedantic -fsanitize=undefined
clang++ -Weverything -fsanitize=undefined

Valgrind 也不抱怨。如果我查看程序集,GCC 只是重用了堆栈中的相同值:

  400789:   48 89 45 f8             mov    QWORD PTR [rbp-0x8],rax
        std::cout << *p;
  40078d:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
  400791:   8b 00                   mov    eax,DWORD PTR [rax]
  400793:   89 c6                   mov    esi,eax
  400795:   bf 60 10 60 00          mov    edi,0x601060
  40079a:   e8 81 fe ff ff          call   400620 <std::basic_ostream<char, std::char_traits<char> >::operator<<(int)@plt>
    }
    std::cout << *p;
  40079f:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
  4007a3:   8b 00                   mov    eax,DWORD PTR [rax]
  4007a5:   89 c6                   mov    esi,eax
  4007a7:   bf 60 10 60 00          mov    edi,0x601060

我知道尊重 NULL 指针是未定义的行为,但是悬空指针呢? (如果是未定义的行为,请提供标准中的引用。)


我希望有人证明这是未定义的行为,而不仅仅是说它没有证据。 duplicate 有很多未引用声明的答案。在 C 中,它明确表示“在其生命周期之外使用对象”是未定义的行为。在 C++ 中,情况并非如此。事实上,§3.8 似乎并没有说任何直接的东西。

请重新打开我的问题,这样我才能得到一些实际的证据,而不是货真价实。

【问题讨论】:

标签: c++ undefined-behavior dangling-pointer


【解决方案1】:

这也是未定义的行为。

C++ 编译器不需要找出每种可能的未定义行为并发出诊断。让编译器尽可能多地捕捉当然更好,而且随着时间的推移,编译器在越来越多的没有通过气味测试的东西上吹哨。

但是,当然,仅仅因为 C++ 编译器没有报错并不意味着代码是正确的。

【讨论】:

  • 我正在寻找支持它是“未定义行为”的参考资料,而不仅仅是货物崇拜和可爱的类比。与 C 不同,C++ 没有直接表示“这是未定义的”的方便引用。据我们所知,代码是明确定义的。
  • 我相当肯定,在 C++ 标准中的某处,指定取消引用指向超出范围且已调用其析构函数的对象的指针是未定义的行为。这是根本。
猜你喜欢
  • 2010-12-21
  • 1970-01-01
  • 1970-01-01
  • 2011-03-13
  • 1970-01-01
  • 1970-01-01
  • 2017-01-25
  • 1970-01-01
  • 2021-03-08
相关资源
最近更新 更多