我们在Visual Studio调试器中得到了一些有趣的行为,如下所示。 我不确定这是代码还是一些调试器的怪异(看过之前的东西)。 我们试图返回一个指向数组中值的指针。
奇怪的行为是,在第二次调用func()之后,x的值会变为等于y ...至少,这就是调试器中出现的内容。
我想我的问题是,这是否合法/安全? 指针应该在main()的作用域中的堆上,所以它应该没问题?
char stuff[100];
char * func()
{
// i is random in the range
stuff[i] = 'a';
return &stuff[i];
}
main()
{
char * x = func();
char * y = func();
}
答案 0 :(得分:2)
您是否正在使用调试版本进行调试?如果您调试发布版本,通常会得到这样的令人惊讶的结果。
调试版本将强制编译器将所有变量放在堆栈上,并保留它们的整个范围,以便获得预期的调试视图。一旦它永远不会再次使用,发布版本可能会为一个变量重用该空间,即使它仍在范围内,并且可能将短期变量保留在处理器寄存器而不是堆栈中。
在发布版本中,x
和y
可能放在同一个内存位置(或寄存器),因为它们的使用寿命不会重叠。在第一行之后不需要保留x
,因此允许编译器丢弃它。如果您稍后在函数中使用x
,那么它将需要在堆栈上拥有自己的空间,因此您可能会按预期在调试器中看到它。
并回答你的问题:是的,这是有效和正确的,只要i
确实在范围内。
答案 1 :(得分:1)
您正在将指针返回到同一个容器中。 x
和y
都指向array
的元素。 array
中执行的任何更改都将通过两个指针显示,因为它们指的是相同的内存区域。
如果您需要不同的结果,则必须动态分配新对象(无论是使用std::string
还是std::vector
明确地或隐含地 - 或推荐)。
答案 2 :(得分:0)
x的指针(存储器地址)的值没有改变。正在修改x指向的内存。
答案 3 :(得分:0)
整个程序有未定义的行为,因为我未初始化。没有什么可以解释的。你很幸运,它没有决定格式化你的硬盘。