2009-12-04 8 views
79

Le code suivant me donne une erreur de segmentation lorsqu'il est exécuté sur une machine 2 Go, mais fonctionne sur une machine de 4 Go.Erreur de segmentation sur les grandes tailles de matrice

int main() 
{ 
    int c[1000000]; 
    cout << "done\n"; 
    return 0; 
} 

La taille du tableau est seulement de 4 Mo. Y a-t-il une limite à la taille d'un tableau qui peut être utilisé en C++?

Répondre

93

Vous êtes probablement en train d'obtenir un débordement de pile ici. Le tableau est trop grand pour tenir dans l'espace d'adressage de la pile de votre programme.

Si vous allouez la baie sur le tas, cela devrait fonctionner, en supposant que votre machine dispose de suffisamment de mémoire.

int* array = new int[1000000];

Mais rappelez-vous que cela va vous obliger à delete[] le tableau. Une meilleure solution serait d'utiliser std::vector<int> et de le redimensionner à 1000000 éléments.

+0

Merci pour la réponse, mais pourriez-vous m'expliquer pourquoi les tableaux sont alloués sur la pile et pourquoi pas dans la mémoire principale du programme. – Mayank

+9

Le code donné est alloué sur la pile car il est spécifié en tant que tableau avec un nombre constant d'éléments lors de la compilation. Les valeurs ne sont mises dans le tas qu'avec malloc, new, etc. –

+3

Toutes les varables automatiques sont allouées sur la pile. Si vous regardez le défaut, vous verrez la taille de vos variables locales soustraite du pointeur de la pile.Lorsque vous appelez malloc ou calloc ou l'une des fonctions mémoire, les fonctions vont et trouvent des blocs de mémoire assez grand pour satisfer votre demande. – rerun

2

Votre tableau est alloué sur la pile dans ce cas essayez d'allouer un tableau de la même taille en utilisant alloc.

46

En C ou C++, les objets locaux sont généralement alloués sur la pile. Vous allouez un grand tableau sur la pile, plus que la pile ne peut gérer, donc vous obtenez un stackoverflow.

Ne l'allouez pas localement sur la pile, utilisez plutôt un autre emplacement. Cela peut être réalisé en créant l'objet global ou en l'affectant sur le tas global. Les variables globales sont correctes si vous n'utilisez pas l'option de n'importe quelle autre unité de compilation. Pour vous assurer que cela ne se produit pas par accident, ajoutez un spécificateur de stockage statique, sinon utilisez simplement le tas.

Cela affectera dans le segment BSS, qui fait partie du tas:

static int c[1000000]; 
int main() 
{ 
    cout << "done\n"; 
    return 0; 
} 

Cette allouera dans le segment DATA, qui fait partie du tas trop:

int c[1000000] = {}; 
int main() 
{ 
    cout << "done\n"; 
    return 0; 
} 
Cette

attribuera à un endroit non précisé dans le tas:

int main() 
{ 
    int* c = new int[1000000]; 
    cout << "done\n"; 
    return 0; 
} 
+0

Si vous utilisez le troisième modèle, en allouant sur le tas, n'oubliez pas de supprimer [] le pointeur à un certain moment ou vous aurez une fuite de mémoire. Ou regardez dans les pointeurs intelligents. – meowsqueak

+6

@meowsqueak Bien sûr, il est bon d'effacer 'partout 'avec' new'. Mais si vous êtes sûr d'allouer de la mémoire une seule fois (comme dans main) il n'est strictement pas nécessaire - la mémoire est garantie d'être libérée à la sortie de main même sans "delete" explicite. – hirschhornsalz

+0

'at'drhirsch (comment faites-vous un personnage de toute façon?) - oui, commentaire juste. Comme le PO semble nouveau à la langue que je voulais juste s'assurer qu'ils, et quiconque d'autre voyant votre bonne réponse, étaient conscients des implications de la troisième option si elle est utilisée en général. – meowsqueak

2

Parce que vous stockez le tableau dans la sta ck. Vous devriez le stocker dans le tas. Voir this link pour comprendre le concept du tas et de la pile.

6

En outre, si vous exécutez dans la plupart des systèmes UNIX & Linux vous pouvez augmenter temporairement la taille de la pile par la commande suivante:

ulimit -s unlimited 

Mais attention, la mémoire est une ressource limitée et avec une grande puissance vient une grande responsabilités :)

+0

Ceci est la solution mais je conseille à tous d'être extrêmement prudent en supprimant ces limites par défaut sur la taille de la pile du programme. Vous subirez non seulement de sévères baisses de performances, mais votre système pourrait tomber en panne. Par exemple, j'ai essayé de trier un tableau avec 16 000 000 éléments entiers avec quicksort sur une machine avec 4 Go de RAM et mon système a été presque tué. LOL – rbaleksandar

+0

@rbaleksandar Je pense que vous ~ 16MB programme presque tuer votre machine parce que vous travailliez avec plusieurs copies de la matrice (peut-être un par appel de fonction?) Essayez une mise en œuvre de mémoire plus;) – RSFalcon7

+0

Je suis assez sûr que la gestion de la matrice ça va puisque je passe par référence et non par valeur. La même chose arrive avec le bubbleort. Enfer, même si ma mise en œuvre de quicksort suce le bubbleort est quelque chose que vous ne pouvez pas implémenter incorrectement. LOL – rbaleksandar

Questions connexes