【问题标题】:Getting segmentation fault if size of two dimensional array is too big如果二维数组的大小太大,则会出现分段错误
【发布时间】:2020-06-14 02:11:38
【问题描述】:

我在下面列出了代码。如果我过多地定义了ARR_SIZE(例如 820),我会收到 segmentation fault 错误。但是,如果ARR_SIZE 不是那么大(例如 320),则代码可以工作。

GDB 仅在 int main() 中显示错误。

我认为问题出在二维数组的初始化阶段,但不确定。

#include "stdio.h"
#include "time.h"
#include "stdint.h"


#define ARR_SIZE 820
#define TICK(X) clock_t X = clock()
#define TOCK(X) printf("time %s: %g sec.\n", (#X), (double)(clock() - (X)) / CLOCKS_PER_SEC)

void copyji(int src[ARR_SIZE][ARR_SIZE], int dst[ARR_SIZE][ARR_SIZE]){
    int i, j;
    for (j = 0; j < ARR_SIZE; j++)
        for (i = 0; i < ARR_SIZE; i++)
            dst[i][j] = src[i][j];
}

void copyij(int src[ARR_SIZE][ARR_SIZE], int dst[ARR_SIZE][ARR_SIZE]){
    int i, j;
    for (i = 0; i < ARR_SIZE; i++)
            for (j = 0; j < ARR_SIZE; j++)
                dst[i][j] = src[i][j];
}


int main(){
    int srcArr1[ARR_SIZE][ARR_SIZE];
    int srcArr2[ARR_SIZE][ARR_SIZE];
    int dstArr1[ARR_SIZE][ARR_SIZE];
    int dstArr2[ARR_SIZE][ARR_SIZE];
    int i, j;
    for (i = 0; i < ARR_SIZE; i++)
        for (j = 0; j < ARR_SIZE; j++){
            srcArr1[i][j] = i - j;
            srcArr2[i][j] = j - i;
        }

    TICK(TIME_JI);
    copyji(srcArr1, dstArr1);
    TOCK(TIME_JI);

    TICK(TIME_IJ);
    copyij(srcArr2, dstArr2);
    TOCK(TIME_IJ);


    return 1;
}

【问题讨论】:

  • 所有数组都放在main 的堆栈帧中的程序堆栈上。在不发出某种系统调用来扩展它的情况下,您可以拥有有限 的堆栈空间(例如 8MB)。将你的数组放在全局/文件范围内,这个限制就被消除了。
  • 您使用了太多堆栈来将参数按值传递给函数copyij!您必须通过引用(指针)传递参数,否则您必须使用全局变量。
  • @SirJoBlack 函数参数永远不会有数组类型。它们实际上是按指针传递,而不是按值传递。这里的问题可能只是main中的变量。
  • 自动变量,如您的 srcArr1 等,在堆栈上分配,这主要是非常有限的。分配内存时需要改为使用堆。
  • @aschepler。你有理由:p ...问题应该是BIG声明进入主要范围。 :p ...

标签: c multidimensional-array segmentation-fault


【解决方案1】:

您遇到此错误是因为您的代码会导致大数组大小(例如 820)的堆栈溢出,而对于较小的大小则不会。您可以使用 malloc 声明您的数组。

使用 malloc 的示例:

int **srcArr1 = (int **)malloc(ARR_SIZE * sizeof(int *));
for (i=0; i<ARR_SIZE; i++) 
         srcArr1[i] = (int *)malloc(ARR_SIZE * sizeof(int));

使用 malloc,您是使用堆而不是堆栈动态分配内存,因此这不会导致 seg。故障。

另一种解决方法是全局或静态声明您的数组,这也从堆而不是堆栈分配内存。

【讨论】:

  • 也许将数组改为 static 或全局数组 - 更多的是一种短期解决方案,但它避免了与 malloc 相关的疑虑和复杂性。
  • @coder,谢谢,这个解决方案解决了我的问题。据我了解,在 for 循环中应该是 srcArr1 而不是 arr。
猜你喜欢
  • 2017-04-18
  • 1970-01-01
  • 2020-06-08
  • 2019-05-11
  • 2018-01-26
  • 2022-01-08
相关资源
最近更新 更多