Erreur de segmentation sur une déclaration de grand tableau

Je veux déclarer un tableau long long non signé avec 2mil. éléments. Lorsque je définis pour la première fois la longueur du tableau const , puis que je définis le tableau, je reçois une erreur de segmentation. Cependant, lorsque je définis la longueur comme non signée long, la déclaration fonctionne.

int main(int argc, const char *argv[]) { const unsigned long long lim = 2000000; //If I omit const, it works. unsigned long long nums2lim[lim]; exit(EXIT_SUCCESS); } 

Est-ce que quelqu’un sait pourquoi la faute de segmentation est levée?

La mémoire automatique (utilisée dans les tableaux locaux) a une limite bien inférieure à la mémoire pouvant être allouée.

Vous pouvez faire pratiquement la même chose avec cela (il utilise des pointeurs)

 #include  int main(int argc, const char *argv[]) { unsigned long long lim = 2000000; unsigned long long *nums2lim=malloc(lim*sizeof(unsigned long long)); free(nums2lim); // don't forget this! return EXIT_SUCCESS; } 

Je n’ai pas été en mesure de reproduire ce problème sur ma boîte SLES 10 (gcc 4.1.2, oui, c’est vieux). Je me fais une erreur de segmentation indépendamment de la façon dont lim est déclaré.

Je vais aller très loin, très loin, sur un membre très maigre et souligner que votre définition du terme main est incorrecte; argv ne doit pas être déclaré const (la norme exige que les chaînes pointées par le tableau argv soient modifiables). Ce comportement indéfini pourrait suffire à faire la différence, mais j’en doute sérieusement.

Quoi qu’il en soit, tenter d’allouer 2 millions d’ objects dans un tableau auto (VLA ou non) est presque toujours mauvais. Peut-être que lorsque la mémoire de l’ordinateur est régulièrement mesurée en téraoctets, ce n’est plus un problème, mais pour le moment, elle sera plus grosse que ce que la stack d’exécution est généralement prête à gérer.

Vous avez quelques options disponibles. Premièrement, vous pouvez déclarer le tableau avec static durée de stockage static , soit en le déclarant à la scope du fichier (en dehors de toute fonction), soit avec le mot clé static . Notez que cela signifie que vous ne pourrez pas utiliser la variable lim pour spécifier la taille (même si vous la déclarez const , lim n’est pas une expression constante ; sa valeur n’est pas connue au moment de la compilation):

 int main( int argc, char **argv ) { static unsigned long long nums2lim[2000000]; ... } 

Alternativement, vous pouvez l’allouer à partir du tas au moment de l’exécution:

 int main( int argc, char **argv ) { const unsigned long long lim=2000000; int *nums2lim = malloc( sizeof *nums2lim * lim ); if ( nums2lim ) { ... } ... } 

Vous feriez cela en C ++ pour allouer des données dans le tas:

 const unsigned long long lim = 2000000; unsigned long long *nums2lim = new unsigned long long[lim]; ... delete [] nums2lim;