为什么此程序每次都在不同的值上对段进行段错误?数组绑定的违规:在不同索引下的段错误
#include <stdio.h>
int main() {
int a[16], i = 0;
while(1) {
a[i] = i;
printf("%d\n", a[i]);
i++;
}
}
为什么此程序每次都在不同的值上对段进行段错误?数组绑定的违规:在不同索引下的段错误
#include <stdio.h>
int main() {
int a[16], i = 0;
while(1) {
a[i] = i;
printf("%d\n", a[i]);
i++;
}
}
我认为这将与C分配内存的方式有关。当您使用行
int a[16]
什么你基本上说的是“我分配足够的内存空间来保存16个整数,开始在给定的点(这个点x
)”。
然后,当你说
while(1) {
a[i] = i;
printf("%d\n", a[i]);
i++;
}
你说,永远,设置ith
指数a
是i
并打印。这项工作起始于x
,然后一次移动一个索引。对于前十六个整数,这很好,因为你已经清除了空间。
但是,当你经过那个时候,你还没有清理空间,所以你不知道那里有什么以及可以覆盖或打印什么。这可能会好一段时间,但是你会发现你无法覆盖内存中的内容(它不是免费的)。此时你会得到你的segfault
。
由于每次运行程序时都会在不同的地方分配空间,因此需要进行不同次数的迭代才能达到内存使用的位置,因此您将在不同的索引处使用segfault
。
解释:为什么代码在i = 16时不是segfault,是因为程序没有分配16 * sizeof(int)字节的内存,而是由操作系统分配给堆栈的整个页面。硬件检测到页面边界违规并引发OS要处理的中断,然后OS将分段信号发送给进程。但是,如果我们多次运行程序,这仍然不能解释我的不同值,因为给予程序的页面大小将始终相同。 – Abhijit
你能链接你从哪里来的? – JCollerton
整个程序被分配一个堆以便进行动态内存分配,但是该函数不会动态分配内存。该函数调用将使用堆栈中的内存来存储局部变量。它将从一个固定大小的堆栈中分配一个块(因为动态内存分配是在堆上完成的),它将根据您给它的数组大小确定该大小。然后,当你超过这个尺寸时,你会得到上面的问题。 – JCollerton
这是什么编程语言?它是C吗?请用正在使用的语言标记您的问题。要更新您的问题,请点击帖子下的**“[edit]”**链接。谢谢。 – Pang