2011-10-21 3 views
1

J'essaie de lire une ligne d'un fichier caractère par caractère et de placer les caractères dans une chaîne; ici » mon code:La ligne de lecture du fichier provoque un plantage

char *str = ""; 
size_t len = 1; /* I also count the terminating character */ 

char temp; 
while ((temp = getc(file)) != EOF) 
{ 
    str = realloc(str, ++len * sizeof(char)); 
    str[len-2] = temp; 
    str[len-1] = '\0'; 
} 

Le programme plante sur la ligne realloc. Si je déplace cette ligne en dehors de la boucle ou si je la commente, elle ne plante pas. Si je ne fais que lire les caractères et les envoyer à stdout, tout fonctionne correctement (c'est-à-dire que le fichier est ouvert correctement). Où est le problème?

Répondre

6

Vous ne pouvez pas realloc un pointeur qui n'a pas été généré avec malloc en premier lieu.

Vous avez également une erreur «off-by-one» qui vous posera problème.

+0

Et je vois que vous avez corrigé le problème de la question originale. Très bien. –

2

Vous ne pouvez pas realloc un littéral de chaîne. En outre, realloc chaque nouveau caractère n'est pas un moyen très efficace de le faire. Regardez dans getline, une extension de GNU.

6

Changer votre code:

char *str = NULL; // realloc can be called with NULL 
size_t len = 1; /* I also count the terminating character */ 

char temp; 
while ((temp = getc(file)) != EOF) 
{ 
    str = (char *)realloc(str, ++len * sizeof(char)); 
    str[len-2] = temp; 
    str[len-1] = '\0'; 
} 

Votre question est parce que vous appeliez realloc avec un pointeur vers la mémoire qui n'a pas été attribué soit malloc ou realloc ce qui est interdit.

De l'realloc manpage:

realloc() changes the size of the memory block pointed to by ptr to size bytes. 
      The contents will be unchanged to the minimum of the old and new 
      sizes; newly allocated memory will be uninitialized. If ptr is NULL, 
      then the call is equivalent to malloc(size), for all values of size; 
      if size is equal to zero, and ptr is not NULL, then the call is 
      equivalent to free(ptr). Unless ptr is NULL, it must have been 
      returned by an earlier call to malloc(), calloc() or realloc(). If 
      the area pointed to was moved, a free(ptr) is done. 

Sur une note de côté, vous devriez vraiment pas pousser le tampon d'un caractère à la fois, mais gardez deux contre, une pour la capacité tampon, et un pour le nombre de caractère utilisé et augmente seulement le tampon quand il est plein. Sinon, votre algorithme aura des performances vraiment médiocres.

+0

Dans la dernière instruction de votre code ('str [len] = '\ 0';'), vous écrivez les limites de la mémoire allouée à 'str'. Il me semble que @Paul a les bons indices. –

+2

@DavidAlber, Paul fait une modification rapide à la question qui n'apparaît pas dans l'histoire. Les indices montrés ici sont de l'original, c'est pourquoi j'ai fait mon "off par un" commentaire dans ma réponse. –

+0

@DavidAlber Merci, j'avais copié le code OP qui contenait cette erreur off-by-one. Je l'ai réparé. –

Questions connexes