Ошибка сегментации, если размер двумерного массива слишком велик - PullRequest
2 голосов
/ 01 марта 2020

Я перечислил код ниже. Если я определяю ARR_SIZE слишком много (например, 820), я получаю ошибка сегментации ошибка. Но если 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;
}

1 Ответ

5 голосов
/ 01 марта 2020

Вы получаете эту ошибку, потому что ваш код вызывает переполнение стека для больших массивов, например, 820, а для меньших - нет. Вы можете объявить свои массивы с помощью malloc.

Пример с использованием mallo c:

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

С помощью mallo c вы динамически выделяете память, используя кучу не стека, так что это не приведет к seg. ошибка.

Другим обходным решением может быть объявление ваших массивов глобально или stati c, это также выделяет память из кучи, а не из стека.

...