问题描述
- 一段奇怪的代码,求解释
- 代码的意思是说,在声明的时候,因为栈的分配原因(先入后出),k[10]就是i的地址。然后i就会被修改成0,循环再次开始,就这样出现了一个死循环。
为什么k[10]就是i的地址呢?int m=1; int i =0; int k[10] = {0}; printf(""&m=%dn""&m); printf(""&i=%dn""&i); printf(""&k[0]=%dn""&k[0]); printf(""&k[9]=%dn""&k[9]); printf(""&k[10]=%dn""&k[10]); for(;i <= 10; ++i) { k[i] = 0; } printf(""HelloWorld!n"");
解决方案
之前关于数据对齐你可以忽略。编译器果然是多为数组预留了2个int的空余,估计还是为了防止数组越界(通常越界1~2个元素的可能性最大)。
解决方案二:
k[10]就是i的地址?这样每次循环到i=10时,i的值就会被修改,肯定就死循环了
解决方案三:
int k[10] = {0};
这个k应该在常量区,不在堆栈上。
而且不同编译器是不同的。
你说的死循环不知道是什么编译器。
解决方案四:
这是在我的VC++2013上
&m=4913620
&i=4913608
&k[0]=4913560
&k[1]=4913564
&k[2]=4913568
HelloWorld!
Press any key to continue . . .
你可以看到根本两个地址相差很远。
而且这么做会触发内存访问违例。
解决方案五:
这个k应该在常量区,不在堆栈上。
这个说的不对
是这样的,k在堆栈上没有错。
但是为了防止越界,我的编译器(你的不一定)为这个数组多分配了一些空间。
解决方案六:
经过测试,要想在我的机器上构成死循环,必须这么写
#include <stdio.h>int main(){ int m = 1; int i = 0; int k[10] = { 0 }; printf(""&m=%dn"" &m); printf(""&i=%dn"" &i); printf(""&k[12]=%dn"" &k[12]); for (; i <= 10; ++i) { k[12] = 0; } printf(""HelloWorld!n"");}
解决方案七:
为什么是12呢?我猜想是因为代码对齐的需要。
在32bit处理器上,通过总线一次性能读取4个字节的数据,所以内存分配都是按照4个字节对齐的。
解决方案八:
因为在内存中k[10]后面就是i,而数组访问越界(只能访问k[9]k[10]已经越界),k[10]就是i,修改了i的值
时间: 2024-08-04 03:35:44