Question

J'ai une fonction qui est appelée plusieurs fois au cours de l'exécution du programme. Dans cette fonction, j'ai un pointeur de caractère dynamique que je remets à la côte à plusieurs reprises.

Ma question est: dois-je libérer ce pointeur avant la fin de la fonction

?
void functionName()
{
 char *variable = (char *) malloc(0);
    //variable is resized with realloc x number of times

 //should free be called here?
 return;
}

Je tiens également à noter que j'ai essayé de libérer le pointeur, cependant, gdb me donne des avertissements quand je le fais.

Était-ce utile?

La solution

Oui, vous devez libérer ou vous fuyez la mémoire. Votre code devrait ressembler à ceci:

void function(void) 
{
    char *variable = (char *)malloc(0);

    variable = realloc(variable, 10);
    // do something with new memory

    variable = realloc(variable, 20);
    // do something with more new memory

    free(variable);  // clean up
}

L'appel malloc(0) est un peu bizarre, je pense.

Autres conseils

Quelques points à faire:

Je ne vois pas comment vous utilisez realloc() dans votre code, mais si vous l'utilisez comme ça, il ne va pas:

variable = realloc(variable, amount);

Quand il est incapable d'allouer plus de mémoire, retourne realloc() NULL mais laisse le pointeur d'origine non modifiée. Dans la ligne ci-dessus, cela signifie que variable est NULL et nous avons perdu l'accès à la mémoire qu'il a, mais que la mémoire n'a pas été libéré. L'idiome correct est le suivant:

void *tmp = realloc(variable, amount);
if(tmp)
  {
    // success! variable invalid, tmp has new allocated data
    variable = tmp;
  }
else
  {
    // failure! variable valid, but same size as before, handle error
  }

La raison pour laquelle vous devez utiliser le second est parce que, avec realloc(), l'échec est mauvais, mais est tout à fait récupérable dans de nombreuses situations, à la différence malloc() où l'échec signifie généralement « arrêter tout et mourir ».

Ceci est une question plus controversée, mais on peut se demander si oui ou non vous devriez jeter la valeur de retour de malloc() et realloc() comme vous le faites. Considérez:

// functionally identical in C
char *a = malloc(10);
char *b = (char *)malloc(10);

En C ++, la distribution doivent être fait, parce que dans C ++ void * ne peut pas être converti implicitement à un autre type de pointeur. (Je pense que cela est une erreur de langage, mais ce n'est pas à moi de juger.) Si votre code est C ++, vous devriez utiliser new et delete de toute façon. Si votre code est C, mais doit compiler avec compilateurs C ++ (pour une raison inepte), vous n'avez pas d'autre choix que de jeter. Si vous n'avez pas besoin de compiler du code C avec les compilateurs C ++ (qui est similaire à avoir à exécuter du code Ruby dans un interpréteur Python), passez aux points ci-dessous, qui sont la raison pour laquelle je pense que vous ne devriez pas jeter.

  1. En C89, si une fonction est utilisée sans être déclarée, il sera déclaré implicitement comme un retour int. Si, par exemple, nous avons oublié de #include <stdlib.h> et nous avons appelé malloc(), la version sans fonte provoquerait une erreur de compilation (moulages implicites de int à char * ne sont pas autorisés), tandis que la version avec le casting serait (à tort) dire au compilateur " Je sais que cela semble fou, mais jetai de toute façon « . La plupart des compilateurs vous donnera un avertissement pour les déclarations implicites (ou INCOMPATIBLES) des fonctions intégrées comme malloc(), mais le casting ne le rendre plus difficile à trouver.

  2. Dites-vous des données:

    float *array = (float *)malloc(10 * sizeof(float));
    

    Plus tard, vous découvrirez que vous avez besoin de plus de précision sur vos données, et doivent faire un tableau de double. Dans la ligne ci-dessus, vous devez changer pas plus de 3 endroits différents:

    double *array = (double *)malloc(10 * sizeof(double));
    

    Si, d'autre part, vous avez écrit:

    float *array = malloc(10 * sizeof *array);
    

    Vous ne devez changer float à double en 1 place. De plus, toujours à l'aide sizeof *obj au lieu de sizeof(type) et ne jamais utiliser des moulages signifie qu'un appel plus tard realloc() peut travailler sans aucune modification , tout en utilisant des moulages et des noms de type explicites nécessiteraient de trouver n'importe où vous avez appelé realloc et de modifier les moulages et sizeofs. De plus, si vous oubliez, et faites ceci:

    double *array = (float *)malloc(10 * sizeof(float));
    

    Sur la plupart des plates-formes, array seront maintenant seulement un tableau de 5 éléments, en supposant que l'alignement n'est pas hors tension et le compilateur ne se plaint pas que vous assigner un float * à un double *. Certains considèrent l'avertissement pour être utile les problèmes du compilateur, car il indique les lignes potentiellement incorrectes. Cependant, si nous évitons sizeof(type) et éviter la coulée, on peut voir que les lignes pas être incorrect, afin d'avoir le compilateur attirer l'attention sur leur est de perdre du temps, nous pourrions utiliser le programme.

A partir des pages de manuel:

Si la taille est 0, malloc () renvoie soit NULL, soit une valeur de pointeur unique qui peut ensuite être transmis avec succès à libérer ().

Alors, je crois que la réponse est "oui":)

.

Oui, vous devez appeler une fois libre () pour libérer le bloc de mémoire. Vous n'avez pas besoin d'appeler gratuitement pour les reallocs suivantes () que vous faites, même si ceux qui renvoient une adresse différente / pointeur. Le gestionnaire de mémoire sait que l'ancien bloc n'est pas nécessaire plus longtemps et libérera (le).

Vous devriez être en mesure d'appeler juste free(variable) à la fin. Si realloc a jamais déplacer les données afin de le redimensionner, il appelle free en interne, vous ne devez pas vous inquiéter à ce sujet.

En outre, lorsque vous initialisez variable, vous pouvez simplement le mettre à NULL au lieu d'appeler malloc; realloc fonctionnera comme malloc la première fois.

Jetez un oeil à quelques-unes des réponses que je l'ai donné à quelques questions en ce qui concerne la gestion de la mémoire:

Toutes le point ci-dessus la chose évidente, pour chaque malloc il est un logiciel gratuit, sinon vous avez une fuite de mémoire , il est donc impératif que vous free la mémoire lorsque vous avez terminé votre variable de pointeur qui est mallocd.

Hope this helps, Meilleures salutations, Tom.

int main(int argc, char *argv[])
{
        char *p = malloc(sizeof(argv[1]));

        p = argv[1];
        printf("%s\n", p);
        free(p);
        return 0;
}

iam obtenir l'erreur glibc

hello
*** glibc detected *** ./a.out: munmap_chunk(): invalid pointer: 0x00007fff66be94c6 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7f38dca1db96]
./a.out[0x4005ed]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7f38dc9c076d]
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top