2014-07-23 2 views
1

Lorsque je tente d'exécuter ce que je reçois une erreur de segmentation:Taille maximale de variable tableau locale

#define FILE_NAME "test.html" 
#define STRING_ARRAY_SIZE 1000000 

int main() { 
fstream file; 
string line = ""; 
string string_array [STRING_ARRAY_SIZE]; 
int i = 0; 

file.open(FILE_NAME); 
while(getline(file, line)) { 
    string_array[i] = line; 
    i++; 
    cout << line << endl; 
} 

file.close(); 
} 

Au lieu de cela, lorsque je tente de compiler cela, il fonctionne:

#define FILE_NAME "test.html" 
#define STRING_ARRAY_SIZE 100000 

int main() { 
fstream file; 
string line = ""; 
string string_array [STRING_ARRAY_SIZE]; 
int i = 0; 

file.open(FILE_NAME); 
while(getline(file, line)) { 
    string_array[i] = line; 
    i++; 
    cout << line << endl; 
} 

file.close(); 
} 

fin de compte, la seule différence est la taille du tableau. Pourquoi ça marche quand c'est 100000, et ça ne marche pas quand c'est 1000000? Quelle est la taille maximale? Je vous remercie.

+2

Les variables locales, y compris les tableaux, sont placées sur la pile, qui a une taille limitée. Sur Windows utilisant VC++, c'est 1 Mo par défaut, sur Linux, c'est typiquement 8 Mo. Essayer d'allouer plus que cela sur la pile provoquera un * débordement de pile * qui conduit à un comportement indéfini et très probablement à un crash. Le nombre maximal de membres dans un tableau n'est pas fixe, mais dépend de la taille des données et de la taille de la pile restante. –

+2

Avez-vous vraiment une erreur de segmentation ** lors de la compilation **? Cela voudrait dire que le compilateur a un bug, ou quelque chose comme de la mémoire défectueuse ... Probablement pas, mais il serait bon de le rendre plus clair. –

+0

vous les gars ont raison. L'erreur de segmentation se produit au moment de l'exécution :) – user3289157

Répondre

2

La limite est spécifique au système (pas seulement matériel, mais aussi logiciel, notamment système d'exploitation et temps d'exécution). Voir aussi this question très semblable au vôtre. Vous devriez essayer d'éviter trop grand call stack frames. Ces jours-ci sur des ordinateurs de bureau ou serveurs, je recommanderais au maximum quelques dizaines de kilo-octets pour les plus grosses trames de pile d'appel (et très souvent beaucoup moins, c'est-à-dire des centaines d'octets). Un système typique a une pile de machine capable de croître jusqu'à quelques mégaoctets (mais sur les microcontrôleurs intégrés, ou à l'intérieur du noyau Linux, cela peut prendre quelques kilo-octets!). Avec les applications multithread, il devrait être un peu moins (puisque chaque thread a sa propre pile).

Sur les systèmes Linux et Posix vous pouvez utiliser le bas setrlimit(2) syscall avec RLIMIT_STACK- (et peut-être parfois légèrement augmenter) la limite de la pile. Dans votre terminal avec un shell bash, utilisez le code interne ulimit -s.

Les options GCC suivantes pourraient vous intéresser: -fstack-usage, -Wframe-larger-than=, -fstack-split

Dans votre code, remplacez

string string_array [STRING_ARRAY_SIZE]; 

avec

vector<string> string_vector; 

et le remplacement

string_array[i] = line; 
i++; 

avec

string_vector.push_back(line); 
3

Il n'y a pas de limite définie par C++ en tant que telle mais plutôt la limite est définie et dépend du matériel que vous utilisez. Fondamentalement, vous pouvez dire qu'il y a deux limites pour la taille du tableau qui est défini par le type (vous pouvez utiliser std::size_t pour vérifier la taille qu'il peut prendre) de l'index utilisé pour définir le tableau et la seconde est la limite de mémoire physique .

En fait, la mémoire est allouée à deux endroits, le premier est sur le tas (mémoire allouée dynamiquement). Ici, la limite de taille est essentiellement une combinaison du matériel disponible et de la capacité du système d'exploitation à simuler l'espace. Et le second est sur la pile (variables déclarées localement). Ici, la limite de taille est ici définie par le compilateur.

+0

La limite est souvent définie par logiciel. Voir ma réponse (et 'setrlimit' sous Linux). –

1

Cela pourrait être 2 choses. Tout d'abord, vous avez besoin de mémoire pour charger des éléments dans un programme. Donc, si vous n'avez pas assez de mémoire, vous aurez un Segmentation fault. Vous ne pouvez pas réserver 1000000 mais vous avez assez de mémoire pour réserver, par exemple, 100000.

Deuxièmement, jetez un oeil à size_t référence. Chaque objet a une limite pour représenter ses données.

1

tout d'abord: dans le temps de la compilation vous ne pouvez pas avoir des erreurs de segmentation, dans le temps de la compilation, il est appelé « erreur de compilation », et le code semble correct ci-dessus.

Et comme toujours: cela dépend. Il y a des limitations dans la pile de mémoire et cela dépend de la plateforme.