为什么我是以下代码的输出10
而不是错误?不是object2
悬空指针吗?
#include <iostream>
using namespace std;
int *method()
{
int object = 10;
return &object;
}
int main()
{
int *object2 = method();
cout << *object2;
}
谢谢!
为什么我是以下代码的输出10
而不是错误?不是object2
悬空指针吗?
#include <iostream>
using namespace std;
int *method()
{
int object = 10;
return &object;
}
int main()
{
int *object2 = method();
cout << *object2;
}
谢谢!
您确实得到了一个悬空指针,因为它指向不再分配的内存,并且您对它的取消引用构成了未定义的行为。
这种情况下的行为恰好是:地址仍然有效,并且没有被其他任何内容覆盖。
编译器不会浪费时间在所有内容上写入零,以防万一您取消引用一个悬空指针,但是您可以通过使用 valgrind 或类似方法运行,或者通过在检索指针和取消引用它之间执行一些其他函数调用来验证它是否真的悬空.
为什么我是以下代码 10 的输出而不是错误?
因为未定义的行为是未定义的。具体来说,不会发生任何事情来覆盖曾经包含的内存object
,因此在您取消引用悬空指针时该值没有改变。如果您尝试再次打印它,您可能会看到不同的东西。或者不是 - 未定义的行为可以做任何事情。
不是
object2
悬空指针吗?
是的。取消引用悬空(或其他无效)指针会产生未定义的行为,所以不要这样做。
您应该能够通过启用编译器警告来避免这种情况;在 GCC 上,特定警告由 启用-Wreturn-local-addr
,但我强烈建议您构建至少-Wall -Wextra -Werror
以捕获尽可能多的潜在错误。
您编写的代码不是错误,而是未定义的行为。
两者gcc
都会valgrind
检查你。
main.cpp: In function 'int* method()':
main.cpp:7:7: warning: address of local variable 'object' returned [-Wreturn-local-addr]
int object = 10;
^
main.cpp: In function 'int main()':
main.cpp:16:21: warning: 'object' is used uninitialized in this function [-Wuninitialized]
cout << *object2;
==22403== Conditional jump or move depends on uninitialised value(s)
==22403== at 0x4C99D61: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.tcc:870)
==22403== by 0x4C9A2FC: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.h:2475)
==22403== by 0x4CA5C1D: std::ostream& std::ostream::_M_insert<long>(long) (locale_facets.h:2336)
==22403== by 0x4007A3: main
==22403==
等等......这是一个编程错误,而不是编译器错误。正如其他人所说,这是未定义的行为。编译器不需要诊断未定义的行为。这就是为什么你应该打开警告。
这是未定义的行为,g++ 会发出警告:
main.cpp:7:7: warning: address of local variable 'object' returned [-Wreturn-local-addr]
int object = 10;
http://coliru.stacked-crooked.com/a/ca3950756cefa9b7
你可以得到任何结果,正确的值,0 -> 无穷大,也可以崩溃等等。它被称为Undefined Behavior。
如果你使用 g++,我建议添加:-Werror=return-local-addr,那么你会得到一个很好的错误而不是警告:
main.cpp:7:7: error: address of local variable 'object' returned [-Werror=return-local-addr]
int object = 10;
不确定,因为您可以使用哪个版本 - 我想这是 g++ 的全新补充
为什么我是以下代码 10 的输出而不是错误?
您正在返回函数临时变量的地址。在函数返回后取消引用这样的地址是未定义的行为。这意味着可能会发生奇怪的事情,您可以自己看到。
object2 不是悬空指针吗?
是的。