【问题标题】:Segmentation fault on large array declaration [duplicate]大型数组声明的分段错误[重复]
【发布时间】:2015-07-14 01:55:04
【问题描述】:

我想声明一个 2mil 的 unsigned long long 数组。元素。当我第一次定义数组 const 的长度然后定义数组时,我得到一个分段错误错误。但是,当我将长度定义为 unsigned long long 时,声明有效。

int main(int argc, const char *argv[])
{
    const unsigned long long lim = 2000000; //If I omit const, it works.
    unsigned long long nums2lim[lim];

    exit(EXIT_SUCCESS);
}

有人知道为什么会抛出分段错误吗?

【问题讨论】:

  • 这看起来不像 C++
  • 您的堆栈很可能不够大,无法容纳 200 万个 unsigned long long。
  • 局部变量,包括数组,存放在栈中,栈是有限的。在 Windows 上,默认堆栈仅为 1 MB,在 Linux 上为 8 MB。您的数组几乎是 16 MB。
  • “有人知道为什么会抛出分段错误吗?” 很可能是因为 8*2000000 超出了您的可用堆栈大小。
  • 如果删除了 const 限定符,这些都不能解释为什么声明“有效”(不会出现段错误)。那很有意思。您使用的是什么编译器(gcc、Visual Studio、...)?

标签: c arrays


【解决方案1】:

您可以在 C++ 中执行此操作以在堆中分配数据:

const unsigned long long lim = 2000000;
unsigned long long *nums2lim = new unsigned long long[lim];
...
delete [] nums2lim;

【讨论】:

  • 问题标记为 C,因此没有 newdelete 表达式。还有@TheParamagneticCroissant,也没有std::vector
  • @JoachimPileborg 抱歉,错过了删除 C++ 标签。我讨厌人们同时使用 C++ 和 C 标记他们的问题,然后删除其中一个。这是错误的。
【解决方案2】:

自动内存(用于本地数组)有一个远低于可分配内存的限制。

你几乎可以用这个做同样的事情(它使用指针)

#include <stdlib.h>

int main(int argc, const char *argv[])
{
    unsigned long long lim = 2000000;
    unsigned long long *nums2lim=malloc(lim*sizeof(unsigned long long));

    free(nums2lim); // don't forget this!

    return EXIT_SUCCESS;
}

【讨论】:

  • 当不再需要数组时使用free
  • @ChronoTrigger,是的,我在发布答案时总是忘记这一点......谢谢你注意到这一点,我会编辑我的帖子。
  • 确实这是一个不错的方法,但这并不能解释为什么当我将 lim 声明为 cont unsigned long long 时它会崩溃。
【解决方案3】:

我无法在我的 SLES 10 机器上重现此行为(gcc 4.1.2,是的,它很旧)。无论lim 是如何声明的,我都会遇到段错误。

我要走,走,走,一个非常瘦的肢体,并指出你对main的定义是不正确的; argv 不应声明为 const(标准要求 argv 数组指向的字符串应该是可修改的)。那一点未定义的行为可能足以造成差异,但我严重怀疑。

无论哪种方式,尝试在auto 数组(VLA 与否)中分配 200 万个anything 几乎总是很糟糕。也许当计算机内存以 TB 为单位定期测量时,它不再是问题,但现在它会比运行时堆栈通常准备处理的更大。

您有几个可用的选项。一,您可以使用static 存储持续时间声明数组,方法是在文件范围(任何函数之外)或使用static 关键字声明它。请注意,这意味着您将能够使用lim 变量来指定大小(即使您声明它constlim 不是常量表达式;它的值在编译时是未知的):

int main( int argc, char **argv )
{
  static unsigned long long nums2lim[2000000];
  ...
}

或者,您可以在运行时从堆中分配它:

int main( int argc, char **argv )
{
  const unsigned long long lim=2000000;
  int *nums2lim = malloc( sizeof *nums2lim * lim );
  if ( nums2lim )
  {
    ...
  }
  ...
}

【讨论】:

    猜你喜欢
    • 2011-12-27
    • 1970-01-01
    • 2013-11-15
    • 2016-03-29
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多