【问题标题】:C programming, why does this large array declaration produce a segmentation fault?C编程,为什么这么大的数组声明会产生分段错误?
【发布时间】:2011-03-04 06:11:11
【问题描述】:

此代码在数组声明期间产生分段错误。我很困惑为什么会发生这种情况。我故意选择 2000000000 作为值,因为它低于 2^31 并且可以放入整数变量中。

int main()
{

    int  nums_size = 2000000000;

    int nums[nums_size];

    int i;
    for(i = 0; i < nums_size; i++) {
        nums[i] = i;
    }


    return 0;

}

【问题讨论】:

标签: c arrays integer


【解决方案1】:

嗯,一方面,这是 20 亿个整数。如果您有一个 32 位地址空间并且int 在您的平台上具有 4 个字节的大小(对于 32 位平台来说是典型的),那么您不能存储那么多整数,句号。

即使如此,堆栈上的可用空间也只有这么多,而堆栈正是自动变量所在的位置。

如果您需要一个非常大的数组,您应该使用 malloc() 动态分配它(如果这样做,请确保在完成后使用 free() 释放它!)。

【讨论】:

  • 即使不是这样,2000000000*4 = 32 位平台上的 8,000,000,000 字节。这几乎是 2^33,超过了可用内存。
  • @Chris:是的——直到我发帖后,我才真正数零。这是很多整数!
  • 通常也可以分配具有静态存储持续时间的非常大的数组。
  • @caf: 是的,尽管我总是不愿意建议——我不得不维护和返工太多的遗留代码,这些代码不是为可重入而设计的,但需要用于多线程软件。 :-P 你是对的,不过:在某些情况下,静态数组是正确的解决方案。
  • 是的 - 都是真的,尽管我建议在大多数情况下分配一个 8GB 工作数组往往会使函数在所有实际用途中都不可重入;)
【解决方案2】:
int  nums_size = 2000000000;

int nums[nums_size];

并不意味着 2000000000 个字节的 int,它意味着 2000000000 个 int 类型的元素,这在 32 位平台上意味着您消耗了将近 8GB 的​​内存——这是不可能的。

【讨论】:

  • ... 在堆栈上! - Kaboom!
【解决方案3】:

您正在堆栈上分配一个巨大的数组。几乎没有 C/C++ 编译器能正确处理。

您也许可以将其移入全局变量(它将通过在编译时映射可执行文件中的内存来静态分配空间),或者切换到 malloc'd 数组。

当然,这仍然是一次性要求的大量内存,但至少我提到的方法可以避免 立即 segfault。

【讨论】:

  • 编译器会正确处理它(如果它在 2^32 内存大小内),但操作系统不允许堆栈变得那么大。
  • 不仅仅是 C/C++ 几乎所有基于堆栈分配的语言(即几乎所有)
【解决方案4】:

局部变量在栈上分配。为应用程序提供了固定数量的堆栈空间(通常为 1MB–8MB,因操作系统而异)。一般规则是使用 malloc() 分配大量数据。

【讨论】:

    【解决方案5】:

    您的问题的答案很简单:stackoverflow。不不不,不是站点,而是“溢出堆栈”的实际过程。您没有足够的 stack 来存储该数组。就如此容易。在内存受限的系统上这样做是纯粹的疯狂。另见this question

    【讨论】:

      【解决方案6】:

      这个版本在我的电脑上运行良好:

      const int nums_size = 2000000000;
      int nums[nums_size];
      
      int main()
      {
          int i;
          for(i = 0; i < nums_size; i++) {
              nums[i] = i;
          }
      
          return 0;
      }
      

      (好吧,说实话。它开始很好,但很快就会进入交换状态。)

      【讨论】:

      • 我猜你的版本是在 64 位平台上运行的。从他的 2^31 评论来看,他绝对没有运行 64 位操作系统。
      • @Chris 2^31 的评论并没有告诉你你是在运行 32 位还是 64 位。我认为 gcc 在 64 位平台上默认为 32 位整数。
      猜你喜欢
      • 2011-01-27
      • 2015-07-23
      • 1970-01-01
      • 2013-05-01
      • 1970-01-01
      • 2017-10-14
      • 2017-01-29
      • 1970-01-01
      相关资源
      最近更新 更多