2013-04-04 3 views
1

У меня есть файл, который имеет 5 миллионов строк и 4 столбца. Как обычно, я пытаюсь прочитать данные в массиве 5 миллионов на 4.Как выделить память для очень большого двумерного массива в C

long M = 5000000; 
double *coordinates[M]; 
for (i = 0; i < M; i++){ 
    coordinates[i] = (double *) calloc(3, sizeof(double)); 
} 

Но когда я запускаю этот код, он имеет ошибку сегмента. После поиска ответа в Интернете, я знаю, это потому, что в стеке не так много памяти. Кто-то предложил выделить память в куче с помощью malloc, если массив одномерный. Но мне нужен двумерный массив, и мне действительно нужно столько памяти, я надеюсь, что кто-то может мне помочь. Большое спасибо.

+2

Это ... ОГРОМНОЕ. – Mido

ответ

2

Вы можете изменить

double *coordinates[M]; 

в

double **coordinates = malloc(M * sizeof(*coordinates)); 

Убедитесь, что free позже эта память в программе.

for (i = 0; i < M; i++){ 
    free(coordinates[i]); 
} 
free(coordinates); 
+0

Спасибо. Это работает хорошо. Кстати, поскольку malloc не может инициировать буфер, есть ли другие варианты, которые могут выполнять распределение и инициирование в одно и то же время? –

+0

Попробуйте calloc! или malloc, а затем memcpy – Marco

+1

@JinYan Вы можете использовать 'calloc (M, sizeof (* координаты))', чтобы выделить память и инициализировать ее до нуля – simonc

0

Вы пытаетесь объявить этот массив в стеке вместо кучи, которая приводит к ошибке переполнения стека.

Попробуйте следующее ...

double** coordinates = malloc(sizeof(double*) * M); 
3

Вам действительно нужен дополнительный слой указателей?

size_t M =98; 
double (*coordinates)[4] = calloc(M, sizeof *coordinates); 

и все готово. coordinates[234329][3]=3.1415926535; все работает.

+0

Ваш вызов 'calloc()' неверен. В противном случае мне нравится этот ответ. –

+0

@FredLarson: я исправил 'calloc' для jthill, рассмотрел upvote (я только что дал). –

+0

@larsmans: Спасибо. Думаю, я тоже исправился. Upvoted. –

2

Как все говорили, проблема в том, что вы пытаетесь выделить этот массив в стек вашей функции. Но что, если у вас есть этот массив, определенный как статический в вашем коде? (Как глобальная переменная или статическая переменная в вашей функции?) Она не должна выделяться каждый раз, когда вы вызываете вашу функцию.

Это позволит избежать вызовов в malloc и calloc (за счет использования массива фиксированного размера вместо динамического).

#include <stdio.h> 
#include <stdlib.h> 
#define ROWS 10000000 
#define COLS 4 
double coordinates[ROWS][COLS]; 

int main() { 

    for (int i = 0; i < ROWS; i++) { 
     for (int j = 0; j < COLS; j++) { 
      coordinates[i][j] = 1.0; 
     } 
    } 

    printf("%.4f\n", coordinates[0][2]); 

    return 0; 
} 

Разница между автоматическим и статическим переменным является то, что автоматическим переменным живет внутри ваши функций (возможно, они распределены каждый раз, когда вы называете вашу функцию, в то время как статические переменным имеет свое значение навсегда, и, вероятно, выделяются только один раз) ,

Что-то в этом роде. Я использую C99, так что вы можете скомпилировать его с .. c99

или GCC -std = c99

или CC = c99 сделать файл

Кроме того, в Linux (и я думаю, что в окнах тоже) вы можете increase the stack size of your program.

Смежные вопросы