2012-08-28 4 views
2

principal:pointeur char libre à l'intérieur d'une fonction

char *tmpip; 
tmpip = get_public_ip(); 

fonction get_public_ip:

char * get_public_ip(void){ 
    char *ipresult; 

    if(((ipresult = malloc(17))) == NULL){ 
     perror("malloc on pub ip"); 
     exit(1); 
    } 


    if(fgets(ipresult, 16, tmpfp) == NULL){ 
     perror("fgets error pubip"); 
     exit(1); 
    } 
    fclose(tmpfp); 
    return ipresult; 
} 

Ma question est:
il est bon de faire à l'intérieur de la principale free(tmpip) ou il est faux?

Répondre

4

C'est un bon moyen de codage: vous malloc() de la mémoire dans une fonction et free() quand il n'est plus nécessaire. Soyez sûr de commenter votre fonction ou le prototype qu'il va malloc() la mémoire nécessaire, donc vous savez que vous devez free() il.

+0

ok merci beaucoup :) – polslinux

+1

vous devez fondamentalement 'libérer 'tout sur le même niveau que vous les' malloc'ed ', en comptant une fonction de création (comme la vôtre, laquelle malloc et retourner) au niveau auquel elle est appelée. – Eregrith

1

Pourquoi est-ce que ce serait une erreur? Vous n'avez pas vraiment d'autre option pour libérer le buffer alloué ailleurs ... Il est idiomatique en C d'appeler une fonction qui alloue de la mémoire, puis de rendre la fonction caller (outer) resposable pour libérer cette mémoire.

+0

j'ai eu un doute avec 'free (tmpip)' et 'free (& tmpip)' ... – polslinux

+0

@polslinux 'free (tmpip)', l'autre option n'a pas de sens –

1

Si l'allocation dynamique est utilisée, libérer le pointeur avec free(tmpip) est définitivement bon! La fonction get_public_ip a juste besoin de documenter que pour libérer des ressources, l'appelant doit s'assurer que free est appelée sur la valeur de retour.

Une alternative serait de fournir une fonction void free_public_ip(char*buf) {free(buf);}, et de documenter que pour libérer des ressources, l'appelant doit l'utiliser. Cela vous donne une certaine flexibilité dans le futur pour changer la façon dont la mémoire est allouée, sans changer de code. Ce n'est certainement pas nécessaire. A mon avis, cela n'a pas vraiment de sens pour un petit tampon de taille fixe comme ça. Le fichier d'en-tête pour get_public_ip pourrait #define PUBLIC_IP_SIZE (17) et prendre un paramètre char*, l'appelant pourrait faire:

char tmpip[PUBLIC_IP_SIZE]; 
get_public_ip(tmpip); 
// no more thinking required 

Au lieu de:

char *tmpip = get_public_ip(); 
// code here, perhaps does more things that could fail, 
// maybe some thinking required to ensure every code path passes through: 
free(tmpip); 

Si ce nombre 17 peut changer à l'avenir, sans la possibilité de ré compiler le code appelant (par exemple s'il s'agit d'une bibliothèque et que vous avez besoin d'une compatibilité binaire), l'allocation dynamique serait justifiée.