我发现很难找到这样的问题的具体答案,但我会解释我认为这应该(不)工作的方式,也许有人可以告诉我我在哪里&# 39;我错了。
我在main中创建一个大小为10的整数数组,它存在于堆栈中。然后我使用for循环将整数0-9加载到该数组中。当for循环结束时,堆栈指针返回到初始化arr1之后的位置,但这些值仍然存在于内存中,并且数组仍然指向它们。
然后,我使用另一个for循环来泛洪堆栈,它应该覆盖在第一个for循环中创建的值,现在当我去访问arr1中的值时,它们应该指向值为5000的整数。
当我打印数组时,它仍然打印出数字0-9。为什么这样做?我认为当循环超出范围时,循环中声明的数据会从堆栈中弹出。感谢
int main(void)
{
int arr1[10];
for(int i = 0; i < 10; i++)
arr1[i] = i;
for(int i = 0; i < 500; i++)
int a = 5000;
for(int i = 0; i < 10; i++)
cout << arr1[i] << endl;
system("PAUSE");
return 0;
}
答案 0 :(得分:2)
不,数组不是“指向”值。 arr1
是10个整数,它不是10个整数指针。值存储在数组中。创建并立即销毁另一个变量a
,即使执行500次,也不会更改数组arr1
中存储的内容。
您可能来自一种语言,根据定义,变量和/或数组元素是对象的引用。在C ++中并非如此。
对于它的价值,当你进入和退出for
循环时,C ++实现通常不会移动堆栈指针。通常它们只为每个函数生成一个包含所有函数需要的变量的堆栈帧,尽管只要它们在正确的时间调用析构函数,它们就可以做他们喜欢的事情。
答案 1 :(得分:2)
您似乎在C ++中误解了数据生命周期。当在作用域块中声明本地数据时(无论是在函数,循环还是其他控制结构中),它将保留在堆栈中,直到该作用域块结束。
这意味着arr1
的全部内容仍然会分配到堆栈中,直到main()
完成,无论你做什么。它不会被同一函数中的后续局部变量覆盖,也不会被嵌套在更深的范围块中的变量覆盖。
在第二个循环中,变量a
(理论上)在循环体的每次迭代上创建和销毁。这意味着你在循环期间堆栈上没有500个a
实例 - 你只有一个。 (实际上,编译器几乎肯定会优化它,因为它没有做任何有用的事情。)
答案 2 :(得分:0)
正如你所说的那样“当循环中超出范围时,循环中声明的数据会从堆栈中弹出。”那是真实的。但是在您的示例中,数组未在循环内声明。它在循环之外声明,并且仍然在main()的其余部分的范围内。
如果你有这样的事情:
char * arr1[10];
for(int i = 0; i < 10; i++)
{
char * text[16];
sprintf(text, "%d", i);
arr1[i] = text;
}
for(int j = 0; j < 10; ++j)
printf ("%s\n", arr1[i]);
然后这会崩溃,因为text []数组在第一个循环内声明,并且它们在循环结束时超出范围,留下指向超出范围的变量的指针。我想这就是你的想法。
答案 3 :(得分:0)
arr1
和a
位于完全独立的内存位置。你可以用这一行证明这一点:
printf("%lu %p %p %p", \
sizeof(int), (void *)&arr1[0], \
(void *)&arr1[9], (void *)&a);
例如,在我的机器上我得到了这个输出:
4 0x7fff5541e640 0x7fff5541e664 0x7fff5541e63c
如您所见,&a
是来自sizeof(int)
的第一个元素的四个字节(arr1
)。
以下声明:
for(int i = 0; i < 500; i++)
int a = 5000;
没有你怀疑的效果。它只是一次又一次地将值5000
分配给变量a
,或者已经过优化,只进行一次甚至完全没有,因为未使用a
。