在C中是否有任何方法可以知道以前是否已使用free()释放了内存块?我能做点像......
if(isFree(pointer))
{
//code here
}
答案 0 :(得分:8)
好的,如果您需要检查指针是否已被释放,您可能需要检查您的设计。您永远不必跟踪指针上的引用计数或是否已释放它。另外一些指针不是动态分配的内存所以我希望你的意思是用malloc()调用的。这是我的观点,但如果你有一个坚实的设计,你应该知道你的指针指向的东西何时被使用。
我看到的唯一不起作用的地方是单片内核,因为内存中的页面需要使用次数,因为共享映射等等。
在您的情况下,只需将未使用的指针设置为NULL并检查它。如果您在malloced结构中有未使用的字段,这将为您提供一种保证的方式。一个简单的规则是,无论何时释放需要以上述方式检查的指针,只需将其设置为NULL,并使用if = = NULL替换isFree()。这样就不需要跟踪引用计数,并且您确定指针是否有效并且没有指向垃圾。
答案 1 :(得分:5)
不,没有办法。
但是,您可以按如下方式使用一些代码规则:
总是始终 始终使用malloc保护分配:
void * vp;
if((vp = malloc(SIZE))==NULL){
/* do something dreadful here to respond to the out of mem */
exit(-1);
}
释放指针后,将其设置为0
free(vp); vp = (void*)0;
/* I like to put them on one line and think of them as one peration */
你想要使用“已释放”功能的任何地方,只需说明
if(vp == NULL)[
/* it's been freed already */
}
我不能真的推荐这个,因为只要你完成了 内存指针应立即超出范围(或至少在 释放它的函数的结尾)这些悬空指针 存在只是不适合我。
这在可能的情况下通常是好的做法;问题是在C的现实生活中往往是不可能的。以一个包含双向链接列表的文本编辑器为例。这个清单很简单:
struct line {
struct line * prev;
struct line * next;
char * contents;
}
我定义了一个分配内存的guarded_malloc
函数
void * guarded_malloc(size_t sz){
return (malloc(sz)) ? : exit(-1); /* cute, eh? */
}
并使用newLine()
struct line * newLine(){
struct line * lp;
lp = (struct line *) guarded_malloc(sizeof(struct line));
lp->prev = lp->next = lp-contents = NULL ;
return lp;
}
我将字符串s
中的文字添加到我的行
lp->contents = guarded_malloc(strlen(s)+1);
strcpy(lp->contents,s);
并且不要狡辩我应该使用有界长度的形式,这只是一个例子。
现在,如何在释放后删除我在line
范围之外创建的char * contents
内容?
答案 2 :(得分:3)
我看到没有人解决为什么你想要什么从根本上是不可能的原因。释放资源(在这种情况下是内存,但基本上适用于任何资源)意味着将其返回到可供重用的资源池。系统能够提供合理答案的唯一方法是“地址X的内存块是否已被释放?”是为了防止这个地址被重复使用,并在其中存储一个状态标志,指示它是否“被释放”。但在这种情况下,它实际上并未被释放,因为它无法重复使用。
正如其他人所说,你试图回答这个问题的事实意味着你需要解决基本的设计错误。
答案 3 :(得分:1)
对于特定于平台的解决方案,您可能对Win32函数IsBadReadPtr(以及其他类似函数)感兴趣。此函数将能够(几乎)预测从特定内存块读取时是否会出现分段错误。
注意:Microsoft已弃用IsBadReadPtr。
但是,在一般情况下,这并不能保护您,因为操作系统对C运行时堆管理器一无所知,并且如果调用者传入的缓冲区没有您期望的那么大,那么其余的从操作系统的角度来看,堆块将继续可读。
指针除了指出的地方外没有任何信息。您可以做的最好的事情是“我知道这个特定的编译器版本如何分配内存,所以我将取消引用内存,将指针移回4个字节,检查大小,确保它匹配......”等等。您无法以标准方式执行此操作,因为内存分配是实现定义的。更不用说他们可能根本没有动态分配它。
另外,我建议您阅读Steve McGuire撰写的“Writing Solid Code”。关于内存管理的优秀部分。
答案 4 :(得分:0)