How to check if a pointer is freed already in C?

2019-01-22 02:31发布

I would like to check if a pointer is freed already or not. How do I do this using gnu compiler set?

标签: c pointers free
7条回答
手持菜刀,她持情操
2楼-- · 2019-01-22 03:14

You can't. Just assign NULL to it after you free it to make sure you don't free it twice (it's ok to free(NULL)).

Better yet, if possible don't write code where you "forget" you already freed it.

EDIT

Interpreting the question as how to find out whether the memory pointed to by a pointer is freed already: you can't do it. You have to do your own bookkeeping.

查看更多
爷、活的狠高调
3楼-- · 2019-01-22 03:19

There is no reliable way to tell if a pointer has been freed, as Greg commented, the freed memory could be occupied by other irrelevant data and you'll get wrong result.

And indeed there is no standard way to check if a pointer is freed. That said, glibc does have functions (mcheck, mprobe) to find the malloc status of a pointer for heap consistency checking, and one of them is to see if a pointer is freed.

However, these functions are mainly used for debugging only, and they are not thread-safe. If you are not sure of the requirement, avoid these functions. Just make sure you have paired malloc/free.


Example 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;
}
查看更多
ゆ 、 Hurt°
4楼-- · 2019-01-22 03:27

You do not, since you cannot.

Keep track of pointers that you obtain from malloc() and only free those, and only once.

If you will, memory has no memory, so it doesn't know whether it is allocated or not. Only your OS's memory manager can tell you that (but C does not include any standardized mechanism to query this information).

查看更多
一夜七次
5楼-- · 2019-01-22 03:36

You can extend the concept of assigning NULL to the pointer value by writing a macro that does it for you. For example:

#define FREE(ptr) do{ \
    free((ptr));      \
    (ptr) = NULL;     \
  }while(0)

Then as long as you make sure your code only uses FREE() and not free(), you can be fairly confident that code you wrote doesn't free the same memory twice. Of course that does nothing to prevent multiple calls into library functions that free memory. And it does nothing to guarantee that there's a free for every malloc.

You can attempt this with a function, but it gets akward because you have to throw in a reference operator and it doesn't look like a normal call to free() anymore.

查看更多
Deceive 欺骗
6楼-- · 2019-01-22 03:36

I know that this answer is a little bit late, but I just read this answer and wrote some code to verify the following:

Free will put the memory block in its own free block list. Normally it also tries to meld together adjacent blocks in the address space. The free block list is just a circular list of memory chunks which have of course some admin data in the beginning. The free-list is also the first location, malloc looks for a new chunk of memory when needed. It is scanned before it calls for new memory from the OS. When a chunk is found that is bigger then the needed memory, it is just divided into two parts. One is returned to caller, the other is put back into the free list.

This code checks only if the first pointer that was allocated is freed:

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);
}

I've tested this code on HP-UX and Linux Redhat and it works, for the case of only one pointer.

查看更多
劫难
7楼-- · 2019-01-22 03:38

You can't. The way to track this would be to assign the pointer to 0 or NULL after freeing it. However as Fred Larson mentioned, this does nothing to other pointers pointing to the same location.

int* ptr = (int*)malloc(sizeof(int));
free(ptr);
ptr = NULL;
查看更多
登录 后发表回答