我想检查指针是否已经释放。我如何使用gnu编译器设置?
答案 0 :(得分:27)
你做不到。跟踪此问题的方法是在释放指针后将指针指定给0
或NULL
。然而正如Fred Larson所提到的,这对指向同一位置的其他指针没有任何作用。
int* ptr = (int*)malloc(sizeof(int));
free(ptr);
ptr = NULL;
答案 1 :(得分:24)
你做不到。只需在NULL
之后为free
分配free(NULL)
,以确保您不会将其释放两次({{1}}即可)。
更好的是,如果可能的话,不要在你“忘记”已经释放它的地方编写代码。
将问题解释为如何找出指针指向的内存是否已经释放:你不能这样做。你必须自己做记账。
答案 2 :(得分:14)
没有可靠的方法来判断指针是否已被释放,正如Greg评论的那样,释放的内存可能会被其他无关数据占用,并且你会得到错误的结果。
确实没有标准方法来检查指针是否被释放。 那说,glibc
确实有函数(mcheck
,mprobe
)来查找heap consistency checking指针的malloc状态,其中一个是要查看指针是否被释放。
但是,这些函数主要用于调试,they are not thread-safe。 如果您不确定要求,请避免使用这些功能。请确保您已配对malloc
/ free
。
#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;
}
答案 3 :(得分:5)
您可以通过编写为您执行此操作的宏来扩展将NULL分配给指针值的概念。例如:
#define FREE(ptr) do{ \
free((ptr)); \
(ptr) = NULL; \
}while(0)
然后,只要你确保你的代码只使用FREE()而不是free(),你就可以相信你写的代码不会释放两次相同的内存。当然,这对防止多次调用释放内存的库函数没有任何作用。并没有什么可以保证每个malloc都有免费的。
你可以用一个函数来尝试这个,但是它变得很麻烦,因为你必须抛出一个引用运算符,它看起来不再是对free()的正常调用了。
答案 4 :(得分:2)
你没有,因为你做不到。
跟踪您从malloc()
获得的指针,并且只释放这些指针,并且只会释放一次。
如果你愿意,记忆没有记忆,所以它不知道它是否被分配。只有您的操作系统内存管理器可以告诉您(但C不包含任何标准化机制来查询此信息)。
答案 5 :(得分:0)
我知道这个答案迟到了a little bit
,但我刚读了this answer并写了一些代码
验证以下内容:
Free会将内存块放在自己的空闲阻止列表中。通常它也会尝试将地址空间中的相邻块融合在一起。空闲块列表只是一个内存块的循环列表,当然在开头有一些管理数据。 自由列表也是第一个位置,malloc在需要时查找新的内存块。 在从操作系统调用新内存之前进行扫描。当发现一个比所需内存大的块时,它只分为两部分。一个返回给调用者,另一个返回到空闲列表中。
此代码仅检查已分配的第一个指针是否已释放:
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);
}
我已经在HP-UX和Linux Redhat上测试了这个代码,只有一个指针就可以了。
答案 6 :(得分:-1)
编写一个函数来捕捉信号 SIGABRT
答案 7 :(得分:-2)
这是我的操作方式:
bool pointer_allocated(void* ptr) {
return ptr != NULL;
}