s = gnu_get_libc_version();
Cela ne fait pas ce que vous croyez. Il semble que vous vous attendiez à ce qu'il remplisse la mémoire que vous avez précédemment allouée, la mémoire qui est pointée par s
.
Qu'est-ce qu'il fait fait est la cause s
à pointera quelque part totalement différent, quelque part qui est décidé par la fonction gnu_get_libc_version
.
Étant donné l'erreur free
et l'utilisation de l'exemple dans le documentation, il y a un meilleur que même la chance cette mémoire est pas allouée dans le tas, en essayant donc de le libérer entraînera un comportement non défini. En supposant que gnu_get_libc_version
renvoie effectivement l'adresse d'une chaîne de style C et qu'elle ne provienne pas du tas (et cela semble certainement être le cas sur le lien ci-dessus), vous n'avez pas besoin d'allouer la mémoire pour il. Au lieu de cela, vous pouvez simplement avoir:
int main(void) {
const char *s = gnu_get_libc_version();
printf("%s\n", s);
return 0;
}
ou même la plus courte (en utilisant puts
et la valeur de retour directement):
int main(void) {
puts(gnu_get_libc_version());
return 0;
}
Si vous ne veulent obtenir les informations de version dans votre propre mémoire tampon allouée (et en supposant que vous avez assez de mémoire pour cela), vous pouvez utiliser:
int main(void){
const char *s = malloc(16);
strcpy(s, gnu_get_libc_version());
printf("%s\n", s); // or puts(s)
free(s);
return 0;
}
Cette copies la chaîne (de la zone retournée de gnu_get_libc_version
) dans votre propre tampon, plutôt que de changer s
pour pointer ailleurs.
Notez que j'ai modifié d'autres éléments dans votre code d'origine. La première consiste à supprimer la distribution explicite de la valeur de retour malloc
.C'est quelque chose qui ne devrait pas être fait en C car il peut cacher certaines erreurs subtiles. C est parfaitement capable de implicitement en renvoyant la valeur de retour void *
à un autre type de pointeur.
La seconde est la distribution en free
qui est également inutile pour la même raison.
La troisième et dernière modification consiste à supprimer la multiplication par sizeof(char)
. Cette valeur est garantie par la norme 1
donc il n'y a aucune raison technique pour laquelle cela est nécessaire.
Qu'est-ce qu'un "numéro de version GNU"? Les Gnous en Afrique ont-ils des versions? Et ne lancez pas de 'void *' dans C! 'free' prend un' void * ', pas un' char * ' – Olaf
Sur la ligne 9, vous avez une fuite de mémoire car votre mémoire allouée est toujours là mais vous la réaffectez à gnu_get_libc_version(). gnu_get_libc_version renvoie un pointeur constant vers la chaîne pour vous. vous essayez de libérer de la mémoire qui n'a pas besoin d'être libérée (la version gnu_get_libc_version), et appeler gratuitement sur tout autre chose que le pointeur de la mémoire dynamique l'amène à vous crier dessus. Indication, le prototype de gnu_get_libc_version est 'const char * gnu_get_libc_version (void); notez le const char *, c'est souvent un indice que la chaîne renvoyée n'est pas destinée à être libérée. – Dmitry
Merci! J'ai réalisé que la question était un peu bête. –