void cleanup(int *int_ptr) {
free(int_ptr);
int_ptr = NULL; // Not working ??
}
int main() {
int a = 8;
int* a_ptr = &a;
cleanup(a_ptr);
printf("%p", a_ptr); // Unexpected: Does not print NULL
}
free(ptr);
ptr = NULL;
// You can use ptr != NULL or ptr != 0, its pretty much the same thing
if(ptr) {
// Pointer is set
} else {
// Pointer has been freed
}
9条答案
按热度按时间bkhjykvo1#
没有可靠的方法来判断指针是否被释放,正如Greg评论的那样,释放的内存可能被其他无关数据占用,你会得到错误的结果。
实际上,没有标准的方法来检查指针是否被释放。* 也就是说 *,
glibc
确实有函数(mcheck
,mprobe
)来查找指针的malloc状态,以进行堆一致性检查,其中一个是查看指针是否被释放。不过,这些函数主要用于调试,they are not thread-safe。**如果您不确定需求,请避免使用这些函数。**只要确保您已配对
malloc
/free
即可。示例http://ideone.com/MDJkj:
gab6jxml2#
您可以通过编写一个宏来扩展将NULL赋值给指针值的概念。例如:
然后只要你确保你的代码只使用FREE()而不是free(),你就可以相当自信地说,你写的代码不会两次释放相同的内存。当然,这并不能阻止多次调用库函数来释放内存。它也不能保证每个malloc都有一个free。
你可以用一个函数来尝试,但它会变得很尖锐,因为你必须抛出一个引用操作符,它看起来不再像是一个正常的free()调用。
tvz2xvvm3#
你没有,因为你不能。
跟踪从
malloc()
获得的指针,并且只释放这些指针,而且只释放一次。如果你愿意,内存没有内存,所以它不知道它是否被分配。只有你的操作系统的内存管理器可以告诉你(但C不包括任何标准化的机制来查询此信息)。
41zrol4v4#
我知道这个答案是
a little bit
晚了,但我只是读了this answer并写了一些代码来验证以下内容:Free会将内存块放入自己的空闲块列表中。通常它也会尝试将地址空间中相邻的块合并在一起。空闲块列表只是一个循环的内存块列表,当然在开始时有一些管理数据。free-list也是第一个位置,malloc在需要时查找新的内存块。在从操作系统调用新内存之前会对其进行扫描。当找到大于所需内存的内存块时,它被分成两部分,一部分返回给调用者,另一部分放回空闲列表。
这段代码只检查分配的第一个指针是否被释放:
我已经在HP-UX和Linux Redhat上测试了这段代码,对于只有一个指针的情况,它可以工作。
8gsdolmq5#
友情提示:如果你在另一个函数中设置了一个指向
NULL
的指针参数,并希望它影响参数(传入的原始指针),则该函数必须接受指向该指针的指针(双ptr)。比如说
这不符合预期。理由:
a_ptr
是一个指针,但它实际上只是一个包含值的变量-所包含的值有点特殊,因为它是一个虚拟内存地址,但它仍然是一个值。当这个值传入cleanup
时,像任何其他变量一样,cleanup
创建该值的本地副本。因此,如果a_ptr
的值为0x7ffd86656848
,int_ptr
也会有值0x7ffd86656848
。当然,将int_ptr
设置为NULL
并不会将a_ptr
设置为NULL
。所以,如果你想设置
int_ptr = NULL
,你必须传入一个双指针。emeijp436#
编写一个函数来捕获信号SIGABRT
eoigrqb67#
我就是这么做的
编辑:这个答案很错误,所以我会更正
如果你想检查指针是否被释放,你可以在释放指针后将其设置为NULL。
如果你不打算再次使用指针,你不需要将指针设置为NULL。在这种情况下,没有任何意义,只会浪费CPU时间。
imzjd6km8#
你不能。跟踪这个的方法是在释放指针后将其分配给
0
或NULL
。然而,正如Fred Larson所提到的,这对指向同一位置的其他指针没有任何影响。3b6akqbq9#
你不能。只要在你
free
它之后分配NULL
给它,以确保你不会释放它两次(free(NULL)
是可以的)。更好的是,如果可能的话,不要在你“忘记”你已经释放了它的地方编写代码。
编辑
将问题解释为 * 如何找出指针所指向的内存是否已被释放 *:你不能这么做你得自己记账