【问题标题】:Segmentation Fault : Core Dumped while initializing large size arrays分段错误:初始化大型数组时核心转储
【发布时间】:2014-05-12 11:34:37
【问题描述】:

在 linux 上,使用 gcc 作为编译器,我得到了臭名昭著的核心转储错误。 全球声明:

#define MAX_N 10000  


double cost[MAX_N][MAX_N]={0};
int stack[MAX_N];
int visited[MAX_N];

错误发生的地方(一旦我注释掉这些行就消失了):

for(q=0;q<5;++q) 
    {
        visited[q]=0;
        stack[q]=0;
    }

这段代码位于一个函数中,该函数被调用了 10,000 多次。所以每次调用函数时,都需要进行这种初始化!我试过使用 memset,但这似乎也没有帮助!

【问题讨论】:

  • 这不一定是错误发生的地方。注释掉这些行可能会改变一些导致其他代码崩溃的东西
  • 10000 不是大尺寸。显然,错误在其他地方。出现这种错误,触发远离源头的故障是正常的。
  • 我如何追踪错误发生的确切位置?
  • 这部分代码没有问题,因为一切都已正确初始化。由于您已经有一个核心转储,您可以将它与gdb 和编译的可执行文件-g 一起使用以获取堆栈跟踪:gdb /path/to/exe /path/to/core,然后执行bt
  • 总结一下。错误不在您提供的代码中。我建议使用 valgrind 工具来检测实际的故障点。您可以搜索 SO 或网络,或使用 valgrind 文档来了解如何使用它来检测段错误。

标签: c arrays fault


【解决方案1】:

我的猜测:

尽管@ivg 说什么,10000 实际上是一个大尺寸。您的声明将占用至少 760Mb,这很容易触及您的硬限制,尤其是在运行时增加堆栈大小时(您通常在函数内部调用函数时这样做)。

我会尝试将该声明移至堆内存空间(即调用 malloc/free)。

【讨论】:

    【解决方案2】:

    如果这些数组是在文件范围内声明的,则它们具有静态存储持续时间并存储在 .bss 段中。

    如果这些数组是在本地范围内声明的,它们将存储在堆栈中。

    在任何一种情况下,您都在使用极大量的内存,这很可能超过了给定系统上.bss 或堆栈的最大限制。

    假设sizeof(double) == 8sizeof(int) == 4,那么你已经分配了

    (8 * 10000 * 10000) + (4 * 10000) + (4 * 10000) = 800,080,000 bytes
    

    大约 780Mb 的空间。

    这样的大量内存应该分配在堆上。

    【讨论】:

      【解决方案3】:

      您可能有堆栈溢出。这通常没有明显的症状,只是奇怪的崩溃。最明显的尝试是将你的大数组设为static,或者改用动态分配。

      【讨论】:

      • 从发布的代码中我们可以看到,数组已经具有静态存储时长。
      • 他说这段代码出现在函数内部。
      • 我不认为数组是在函数内部声明的,还是只是循环 sn-p。无论如何,static 解决不了问题,只是将它移到别处。动态分配是唯一正确的解决方案。
      猜你喜欢
      • 2021-01-06
      • 1970-01-01
      • 2020-07-23
      • 1970-01-01
      • 1970-01-01
      • 2020-04-18
      • 2020-07-14
      • 2015-06-25
      相关资源
      最近更新 更多