0

为什么此程序每次都在不同的值上对段进行段错误?数组绑定的违规:在不同索引下的段错误

#include <stdio.h> 
int main() { 

    int a[16], i = 0; 
    while(1) { 
    a[i] = i; 
    printf("%d\n", a[i]); 
    i++; 
    } 
} 
+0

这是什么编程语言?它是C吗?请用正在使用的语言标记您的问题。要更新您的问题,请点击帖子下的**“[edit]”**链接。谢谢。 – Pang

回答

0

我认为这将与C分配内存的方式有关。当您使用行

int a[16] 

什么你基本上说的是“我分配足够的内存空间来保存16个整数,开始在给定的点(这个点x)”。

然后,当你说

while(1) { 
    a[i] = i; 
    printf("%d\n", a[i]); 
    i++; 
} 

你说,永远,设置ith指数ai并打印。这项工作起始于x,然后一次移动一个索引。对于前十六个整数,这很好,因为你已经清除了空间。

但是,当你经过那个时候,你还没有清理空间,所以你不知道那里有什么以及可以覆盖或打印什么。这可能会好一段时间,但是你会发现你无法覆盖内存中的内容(它不是免费的)。此时你会得到你的segfault

由于每次运行程序时都会在不同的地方分配空间,因此需要进行不同次数的迭代才能达到内存使用的位置,因此您将在不同的索引处使用segfault

+0

解释:为什么代码在i = 16时不是segfault,是因为程序没有分配16 * sizeof(int)字节的内存,而是由操作系统分配给堆栈的整个页面。硬件检测到页面边界违规并引发OS要处理的中断,然后OS将分段信号发送给进程。但是,如果我们多次运行程序,这仍然不能解释我的不同值,因为给予程序的页面大小将始终相同。 – Abhijit

+0

你能链接你从哪里来的? – JCollerton

+0

整个程序被分配一个堆以便进行动态内存分配,但是该函数不会动态分配内存。该函数调用将使用堆栈中的内存来存储局部变量。它将从一个固定大小的堆栈中分配一个块(因为动态内存分配是在堆上完成的),它将根据您给它的数组大小确定该大小。然后,当你超过这个尺寸时,你会得到上面的问题。 – JCollerton