2015-10-22 7 views
1

Je ne suis pas familier avec C et j'essaye de trouver une allocation de mémoire dynamique pour la lecture d'un fichier. Au moins, je pense que c'est ce que je fais.Modifier un caractère * par pointeur dans une fonction donne un plantage

Quoi qu'il en soit, ce code fonctionne:

int readfromfile(FILE *filepointer) 
{ 
    size_t size = 2; 
    char *str = (char *) malloc(sizeof(char)); 
    int character = 0; 
    size_t counter = 0; 
    while((character = fgetc(filepointer)) != EOF) 
    { 
     str = (char *) realloc(str, size); 
     str[counter] = (char) character; 
     size ++; 
     counter++; 

    } 
    str[counter] = '\0'; 
    printf("+%s+", str); 
    free(str); 
    return 0; 
} 

Et ce code ne fonctionne pas:

int main() 
{ 
    char *str = (char *) malloc(sizeof(char)); 
    ... 
    readfromfile(ifpointer, &str); 
} 

int readfromfile(FILE *filepointer, char **str) 
{ 
    size_t size = 2; 
    int character = 0; 
    size_t counter = 0; 
    while((character = fgetc(filepointer)) != EOF) 
    { 
     *str = (char *) realloc(*str, size); 
     *str[counter] = (char) character; 
     size ++; 
     counter++; 
    } 
    str[counter] = '\0'; 
    printf("+%s+", *str); 
    free(str); 
    return 0; 
} 

Je ne comprends pas pourquoi, parce que ce que je comprends que je envoie un pointeur vers l'emplacement le tableau char à la fonction et l'accès aux données à chaque fois. Les compilateurs ne montrent aucun message d'erreur, ils ne font que passer une boucle et la deuxième boucle se bloque après le realloc à chaque fois. Le caractère affecté à la première valeur est également garbage. J'ai passé un certain temps à essayer de faire fonctionner cela et j'ai fait beaucoup de recherche, donc je m'excuse si j'ai manqué une solution, mais je suis vraiment bloqué à ce stade.

+1

jamais jeté le résultat de malloc. – Magisch

+0

Il réalloue la mémoire lorsqu'il ajoute plus de caractères, mais ne le fait pas? Et pour ce qui est de libérer de la mémoire, je m'excuse de vérifier qu'il a été libéré, édité maintenant. – JJJ

+0

vous n'avez pas besoin d'ajouter une distribution pour 'malloc' –

Répondre

7

vous obtenez un accident parce que

*str[counter] = (char) character; 

est le même que

*(str[counter]) = (char) character; 

par opposition à

(*str)[counter] = (char) character; 

qui est en fait ce que vous vouliez. Lisez Operator Precedence on Wikipedia. Vous trouverez que [] a plus de priorité que le * (opérateur de déréférencement).

En outre, la distribution ici, ainsi que dans les appels à realloc et malloc, est inutile. N'oubliez pas de vérifier la valeur de retour de realloc, malloc etc pour voir s'ils ont réussi à allouer de la mémoire.

Maintenant, vous avez un autre problème: free(str); dans le deuxième code doit être free(*str);. Notez qu'après que *str a été libéré de la fonction, vous n'êtes pas censé lire ou écrire dans cet emplacement de mémoire de main car il est maintenant devenu invalide pour que vous fassiez une falsification.

+0

Merci beaucoup! Je ne peux pas croire qu'il manque un ensemble de parenthèses m'a causé autant de problèmes, je vais certainement devoir donner lecture de cette pièce. – JJJ

+0

@JJJ La différence entre les deux opérations peut sembler pas très forte, mais ses deux opérations complètement différentes, donc bien sûr les deux entraîneront deux résultats différents. – Magisch

+0

@Cool Guy Ah merci, s'est débarrassé de la fonte maintenant et je suis sur le point d'ajouter dans les vérifications pour realloc/malloc aussi. – JJJ

0

dans votre int readfromfile(FILE *filepointer, char **str) le paramètre char **str est en fait le même que char *str[], ce qui signifie **str attend un tableau de pointeurs char. mais vous passez à ce char *str qui est juste un tableau de char

lorsque vous utilisez ReadFromFile (...) vous devriez le faire de cette façon (quelque chose comme ...):

char *str[2] = {"some char array", "another char array"}; 
readfromfile(ifpointer, str); 

ou :

char *a = "this char array"; 
char **str = &a[0]; 
readfromfile(ifpointer, str); 

vous obtiendrez l'idée ...

+0

"_qui signifie que' ** str' attend un tableau de pointeurs char. "- Non. Il attend un pointeur vers un pointeur vers un' char' (un 'char **') "_however que vous y passez' char * str' qui est juste un tableau de 'char'_" - Non. L'OP passe '& str' qui est un' char ** ', exactement ce que le deuxième argument de' readfromfile' requiert. –