巨大的数组导致分段错误[重复]

Posted

技术标签:

【中文标题】巨大的数组导致分段错误[重复]【英文标题】:Huge array is causing segmentation fault [duplicate] 【发布时间】:2019-03-24 17:53:52 【问题描述】:

我正在尝试读取包含大约 10^7 个值的数据文件并执行一些计算。我正在创建一个该大小的数组并执行fscanf 将这些值读入数组的每个元素中。程序的要点是这样的

#include<stdio.h>
#include<math.h>

int main()

    int L = 10000000;
    float array[L];
    FILE *fp;
    fp = fopen("datafile.txt","r");
    /*
    reading values into the array from datafile.txt using fscanf
    and doing some operations on array elements
    */
    fclose(fp);
    return 0;

但是,如果我使用较小的 L,即 L=10^6 和较小的 L,则相同的程序可以正常工作。 首先,我认为我的笔记本电脑的主内存较小(~4GB),然后我尝试在具有 16GB 和 128GB 主内存的高端计算机上运行该程序,我也得到了segmentation fault(core dumped)

我使用gcc编译程序,编译程序没有任何错误和警告。

gcc my_program.c -lm
./a.out

正如我提到的,输出是分段错误。

【问题讨论】:

数组对于堆栈来说太大了。将数组移出main,或将数组声明为static 有没有声明数组的上限?这里的堆栈是什么意思? @user3386109 en.wikipedia.org/wiki/Call_stack 上限由堆栈大小决定,不同的实现会有所不同。我通常会尽量避免使用大于几 K 字节的数组。第三种选择(除了我在第一条评论中提到的两个之外)是使用 malloc 为数组分配内存。 贴出的代码无法编译!除其他问题外,此语句:fp = fopen("datafile.txt",'r'); 语法错误。第二个参数应该是一个指向字符串的指针,即。 fp = fopen("datafile.txt","r"); 注意使用双引号而不是单引号。你的编译器应该告诉你这个问题。编译时,始终启用警告,然后修复这些警告。 (对于gcc,至少使用:-Wall -Wextra -Wconversion -pedantic -std=gnu11)注意其他编译器使用不同的选项来执行相同的操作 OT:调用函数时:fopen(),始终检查(!=NULL)返回值以确保操作成功 【参考方案1】:

你可能正在耗尽你的筹码。对于任何“大”的东西,使用 calloc 之类的东西动态分配:

int main()

    int L = 10000000;
    float *array = calloc(L, sizeof(float));

    FILE *fp;
    fp = fopen("datafile.txt",'r');
    /*
    reading values into the array from datafile.txt using fscanf
    and doing some operations on array elements
    */
    fclose(fp);

    free(array);
    return 0;

局部变量的大小是有限的,因此试图创建一个“太大”的局部变量会导致不可预知的行为甚至崩溃。局部变量的剩余内存取决于代码嵌套的深度,因此它可能会大幅波动。这就是为什么将局部变量保持在最低限度很重要的原因。指针和整数确实很便宜,但结果大小的数组很麻烦。

【讨论】:

也许calloc(L, sizeof *array) 会更好?只是吹毛求疵。 @Osiris 我不明白为什么会更好。只是看起来很奇怪。 很多C代码都是以能够关注这些事情为前提的,所以这通常不是问题。另一方面,C++ 与 auto 完全不同。 是的,我同意你的观点,我只是想指出,即使在 C 中,有一个选项可以更安全地防止更改类型(实际上只是一个挑剔)。不过,这是一个很好的答案。 在这个例子中,分配和声明在同一个语句中,也许看起来并不重要,但是在声明和分配分开发生的情况下,可能相隔很多行,这要好得多从可维护性的角度来看,使用对象的类型而不是显式类型,因此这是一个有用的习惯。它看起来一点也不奇怪——这是一种很好的做法。我只看到专业人士;你认为有什么缺点?请记住,开发人员和维护人员可能不是同一个人,也可能不是同一技能水平,

以上是关于巨大的数组导致分段错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章

访问全局数组会导致分段错误

用指向数组的指针替换衰减的数组导致分段错误

在 C 中创建大型数组时出现分段错误

为啥我的字符串分配会导致分段错误?

尝试声明大数组时出现分段错误和核心转储[重复]

C - 将结构写入二维数组会导致分段错误