抓住悬空指针

时间:2016-05-23 01:52:08

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

我编写了以下代码,输出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清洁剂我没有得到一点点。

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似乎没有任何远程指示。

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

1 个答案:

答案 0 :(得分:0)

这也是未定义的行为。

不需要C ++编译器来确定并发布有关每种可能的未定义行为的诊断。让编译器尽可能多地捕获它当然更好,并且随着时间的推移,编译器已经越来越好地吹响了越来越多没有通过气味测试的东西。

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