Comment vérifier si un pointeur est déjà libéré en C?
je voudrais vérifier si un pointeur est libérée déjà ou pas. Comment puis-je utiliser le jeu de compilateurs gnu?
6 réponses
vous ne pouvez pas. La façon de suivre ceci serait d'assigner le pointeur à 0
ou NULL
après l'avoir libéré. Cependant, comme Fred Larson l'a mentionné, cela ne fait rien à d'autres pointeurs pointant vers le même endroit.
int* ptr = (int*)malloc(sizeof(int));
free(ptr);
ptr = NULL;
vous ne pouvez pas. Il suffit de lui assigner NULL
après free
pour s'assurer que vous ne le libérez pas deux fois (c'est ok à free(NULL)
).
mieux encore, si possible n'écrivez pas de code où vous "oubliez" que vous l'avez déjà libéré.
EDIT
interpréter la question comme comment savoir si la mémoire pointée par un pointeur est déjà libérée : vous ne pouvez pas le faire. Que vous avez à faire votre propre comptabilité.
il n'y a aucun moyen fiable de dire si un pointeur a été libéré, comme Greg l'a commenté, la mémoire libérée pourrait être occupée par d'autres données non pertinentes et vous obtiendrez un mauvais résultat.
et en effet il n'y a pas de moyen standard pour vérifier si un pointeur est libéré. qui dit , glibc
a des fonctions ( mcheck
, mprobe
) pour trouver le statut malloc d'un pointeur pour vérification de cohérence de tas , et l'un d'eux est pour voir si un pointeur est libéré.
cependant , ces fonctions sont principalement utilisées pour le débogage seulement, et ils ne sont pas thread-safe . Si vous n'êtes pas sûr de l'exigence, d'éviter ces fonctions. assurez-vous que vous avez pairé malloc
/ free
.
exemple http://ideone.com/MDJkj :
#include <stdio.h>
#include <stdlib.h>
#include <mcheck.h>
void no_op(enum mcheck_status status) {}
int main()
{
mcheck(&no_op);
void* f = malloc(4);
printf("%d (should be %d)\n", mprobe(f), MCHECK_OK);
printf("%d (should be %d)\n", mprobe(f), MCHECK_OK);
free(f);
printf("%d (should be %d)\n", mprobe(f), MCHECK_FREE);
printf("%d (should be %d)\n", mprobe(f), MCHECK_FREE);
return 0;
}
vous pouvez étendre le concept d'assigner NULL à la valeur du pointeur en écrivant une macro qui le fait pour vous. Par exemple:
#define FREE(ptr) do{ \
free((ptr)); \
(ptr) = NULL; \
}while(0)
aussi longtemps que vous vous assurez que votre code n'utilise que FREE() et non free(), Vous pouvez être assez sûr que le code que vous avez écrit ne libère pas la même mémoire deux fois. Bien sûr, cela ne fait rien pour empêcher les appels multiples dans les fonctions de bibliothèque qui libèrent la mémoire. Et il ne fait rien pour garantir qu'Il ya un gratuit pour chaque la fonction malloc.
vous pouvez essayer cela avec une fonction, mais il obtient akward parce que vous devez jeter dans un opérateur de référence et il ne ressemble plus à un appel normal à free ().
vous ne le faites pas, puisque vous ne pouvez pas.
gardez la trace des pointeurs que vous obtenez de malloc()
et ne libérez ceux-ci, et une seule fois.
si vous voulez, la mémoire n'a pas de mémoire, donc elle ne sait pas si elle est attribuée ou non. Seul le gestionnaire de mémoire de votre système D'exploitation peut vous le dire (mais C n'inclut aucun mécanisme standardisé pour interroger cette information).
je sais que cette réponse est a little bit
en retard, mais je viens de lire cette réponse et a écrit un certain code à
vérifier ce qui suit:
Libre volonté de mettre le bloc de mémoire dans son propre bloc libre liste . Normalement, il essaie aussi de souder des blocs adjacents dans l'espace d'adresse. La liste des blocs libres n'est qu'une liste circulaire de morceaux de mémoire qui ont bien sûr des données admin au début. Le libre-liste est également le premier emplacement , malloc cherche un nouveau morceau de mémoire lorsque nécessaire. il est scanné avant qu'il ne demande une nouvelle mémoire à partir de L'OS . Lorsqu'un bloc est trouvé qui est plus grande que la mémoire nécessaire, il est simplement divisé en deux parties. On est retourné à l'appelant, l'autre est remis dans la liste libre.
ce code ne vérifie que si le premier pointeur attribué est libéré:
int is_freed(void *p)
{
void * q;
char p_addr [50];
char q_addr [50];
sprintf(p_addr, "%p", p);
q = malloc (1);
sprintf(q_addr, "%p", q);
free (q);
return ! strcmp(q_addr, p_addr);
}
j'ai testé ce code sur HP-UX et Linux Redhat et il fonctionne, pour le cas d'un seul pointeur.