为什么我是以下代码10
的输出而不是错误? object2
不是悬空指针吗?
#include <iostream>
using namespace std;
int *method()
{
int object = 10;
return &object;
}
int main()
{
int *object2 = method();
cout << *object2;
}
谢谢!
答案 0 :(得分:2)
你做得到一个悬空指针,因为它指向不再分配的内存,你对它的取消引用构成了未定义的行为。
这种情况中的行为恰好是:地址仍然有效,并且没有被其他任何地方覆盖。
编译器不会浪费时间在所有内容上写入零,以防您取消引用悬空指针,但是您可以通过运行valgrind或类似程序或通过执行某些其他功能来验证它是否真的悬空在检索指针和解除引用之间调用。
答案 1 :(得分:2)
为什么我是以下代码10的输出而不是错误?
因为未定义的未定义行为。具体来说,没有任何事情可以覆盖以前包含object
的内存,因此在取消引用悬空指针时,该值不会发生变化。如果您再次尝试打印它,您可能会看到不同的东西。或者不 - 未定义的行为可以做任何事情。
Isn&#39; t
object2
悬挂指针?
是。取消引用悬空(或其他无效)指针会产生未定义的行为,所以不要这样做。
您应该可以通过启用编译器警告来避免这种情况;在GCC上,-Wreturn-local-addr
启用了特定警告,但我强烈建议您至少使用-Wall -Wextra -Werror
构建以捕获尽可能多的潜在错误。
答案 2 :(得分:1)
您编写的代码不是错误,而是undefined behavior.
答案 3 :(得分:1)
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==
等......这是编程错误,而不是编译器错误。正如其他人所说,它是未定义的行为。编译器不需要诊断未定义的行为。这就是你应该开启警告的原因。
答案 4 :(得分:1)
这是未定义的行为,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 - &gt;无限,也崩溃等,称为未定义行为。
如果你使用g ++,我会建议添加:-Werror = return-local-addr,那么你会得到一个很好的错误而不是警告:
main.cpp:7:7: error: address of local variable 'object' returned [-Werror=return-local-addr]
int object = 10;
不确定,因为你可以使用哪个版本 - 我想这是g ++的新增内容
答案 5 :(得分:1)
为什么我是以下代码10的输出而不是错误?
您正在返回函数临时变量的地址。返回函数后取消引用此类地址是未定义的行为。这意味着可能会发生奇怪的事情,你可以自己看到它。
不是对象2悬挂指针吗?
是的,是的。