【问题标题】:Array bound violation: segfault at different indices数组边界违规:不同索引处的段错误
【发布时间】:2017-07-28 08:41:26
【问题描述】:

为什么这个程序每次都会在不同的 i 值上发生段错误?

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

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

【问题讨论】:

  • 这是什么编程语言?是C吗?请用使用的语言标记您的问题。要更新您的问题,请点击帖子下方的 "edit" 链接。谢谢。

标签: arrays memory-management segmentation-fault indexoutofboundsexception


【解决方案1】:

我认为这与 C 分配内存的方式有关。当你使用线时

int a[16]

您实质上是在说“在内存中分配足够的空间来容纳 16 个整数,从给定点开始(将此点称为 x)”。

那么当你说

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

你说,永远,将aith 索引设置为i 并打印出来。这可以从x 开始,然后一次移动一个索引。对于前 16 个整数,这很好,因为您已经清除了空间来执行此操作。

但是,当您越过它时,您还没有清除空间,因此您不知道那里有什么以及可以覆盖或打印什么。这可能暂时没问题,但随后您将无法覆盖内存中的内容(它不是免费的)。此时您将获得您的segfault

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

【讨论】:

  • 为什么代码在i = 16时没有segfault的解释是程序没有分配16 * sizeof(int)字节的内存,而是在栈上的一整页被操作系统。硬件检测到页面边界违规并引发中断让操作系统处理,然后操作系统向进程发送分段信号。但是,如果我们多次运行程序,这仍然不能解释 i 的不同值,因为给程序的页面大小将始终相同。
  • 你能链接你从哪里得到的吗?
  • 整个程序被分配了一个堆以便动态分配内存,但是这个函数不会动态分配内存。此函数调用将使用堆栈中的内存来存储局部变量。它将从堆栈中分配一个固定大小的块(因为动态内存分配是在堆上完成的),并且它将根据您给它的数组的大小确定该大小。然后,当您运行超过该大小时,您将遇到上述问题。
  • 您的答案没有解释,为什么程序每次都会在不同的 'i' 值上出现段错误。它只解释了为什么它不会在 i = 16 处出现段错误。
  • 因为程序每次运行时都会在内存中的不同位置分配堆栈。当while 循环在分配给它的内存上运行时,它将运行到相邻的内存中,该内存尚未分配给程序。如果这是免费的,那很好。然而,随着它永远运行,它最终会到达一个不免费的点,即segfaults。因为每次堆栈都在不同的位置,所以与其相邻的空闲内存量每次都会发生变化,这意味着每次迭代都有不同的 i 值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-26
  • 1970-01-01
  • 2018-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多