Impossible d’allouer de la mémoire

Dans mon code C, j’alloue de la mémoire pour un tableau 2D double E[2000][2000]; mais lorsque j’exécute une erreur de Segmentation fault(core dumped) erreur d’exécution Segmentation fault(core dumped) et lorsque je réduis la taille du tableau à environ 900, le code fonctionne correctement.

Pourquoi affiche-t-il une erreur d’exécution depuis que la mémoire double prend 64 bits (norme IEEE), de sorte que le code devrait prendre environ 32 Mo, ce qui n’est pas beaucoup par rapport à la taille de la RAM? des données que je dois stocker est 4000000 chacune sont des nombres à virgule flottante.

Etes-vous en train de déclarer E en tant que variable locale? Si c’est le cas, vous manquez de mémoire de stack.

 void func() { double E[2000][2000]; /// definitely an overflow } 

Utiliser l’allocation dynamic:

 double* E = malloc(2000 * 2000 * sizeof(double)); /// don't forget to "free(E);" later 

Ou si vous avez besoin du tableau 2D, utilisez un zig-zag:

 double** E = malloc(2000 * sizeof(double*)); /* check that the memory is allocated */ if(!E) { /* do something like exit(some_error_code); to terminate your program*/ } for(i = 0 ; i < 2000 ; i) { E[i] = malloc(2000 * sizeof(double)); /* check that the memory for this row is allocated */ if(!E[i]) { /* do something like exit(some_error_code); to terminate your program*/ } } 

Ensuite, la désallocation est un peu plus compliquée:

 for(i = 0 ; i < 2000 ; i) { free(E[i]); } free(E); 

PS Si vous voulez conserver toutes vos données de manière continue, il y a une astuce (code du paquet FFT de Takuya Ooura )

 double **alloc_2d(int n1, int n2) { double **ii, *i; int j; /* pointers to rows */ ii = (double **) malloc(sizeof(double *) * n1); /* some error checking */ alloc_error_check(ii); /* one big memory block */ i = (double *) malloc(sizeof(double) * n1 * n2); /* some error checking */ alloc_error_check(i); ii[0] = i; for (j = 1; j < n1; j++) { ii[j] = ii[j - 1] + n2; } return ii; } void free_2d(double **ii) { free(ii[0]); free(ii); } 

Le vous appelez juste

 double** E = alloc2d(2000, 2000); 

et

 free_2d(E); 

Je suppose que vous l’allouez sur la stack simplement

 double E[2000][2000]; 

qui sera probablement plus que la taille de la stack allouée à votre programme.

Essayez d’utiliser malloc (ou une nouvelle version de c ++) ou d’augmenter la taille de stack par défaut de votre programme à l’aide des options. gcc peut être configuré en utilisant setrlimit () à cette fin.

réglage de la taille de la stack en gcc

N’oubliez pas que même si la taille de la stack est augmentée, un tableau de cette taille doit être global.

Vous pouvez également utiliser une seule instruction pour allouer un tableau 2D sur le tas si une dimension est de taille fixe.

 double (* E)[COLUMN_SIZE]; int rows = 20; // this is dynamic and can be input from user at run time E = malloc(rows * sizeof(*E)); // this needs to be freed latter 

Un exemple similaire plus détaillé allouant un tableau 2D sans boucles

Cela dépend de l’endroit où vous allouez le tableau. L’utilisation de l’espace de stack provoquera probablement un débordement (à moins que vous ne demandiez à l’éditeur de liens d’allouer une stack très volumineuse).

Par exemple, cela pourrait ne pas fonctionner

 int main() { double E[2000][2000]; // Likely an overflow } 

Cependant, déplacer la masortingce vers la zone de mémoire statique

 double E[2000][2000]; int main() { // use E here } 

va probablement éviter le problème.