int *a = malloc(40);
int *b;
b=a;
if( *some conditions* )
free(a);
// I know that 'a' has been allocated this chunk of memory X times
// and free(a) has been called less than X times.
我不知道那个条件,所以不知道'a'是否已被释放!那么现在我怎么能确定'b'即'a'是否已被释放。
答案 0 :(得分:5)
如果要确保对动态分配的内存指针的后续free
调用不会造成任何损害,则应将NULL
分配给该指针。 Because (emphasis added):
free()函数释放ptr指向的内存空间,该内存空间必须由之前调用malloc(),calloc()或realloc()返回。否则,或者如果之前已经调用了free(ptr),则会发生未定义的行为。 如果ptr为NULL,则不执行任何操作。
如果要确保指针b
始终引用另一个指针a
指向的同一对象,可以将b
转换为指向{{1}的指针而是(每次你需要使用它时取消引用它):
a
内存泄漏的另一件事。双重释放内存时,没有内存泄露。在这种情况下,您将偶然发现未定义的行为,在这种情况下任何事情都可能发生。仅仅因为你不能访问不属于你自己的内存区域(c.f., this great post)。 相反,当您松开对动态分配的内存块的引用时,您将泄漏内存。例如:
#include <stdio.h>
#include <stdlib.h>
int main() {
/* dynamically allocate some memory */
int *a = malloc(40);
/* b is a pointer to a pointer to an int */
int **b;
/* make b point to a */
b = &a;
if ( 1 ) {
/* free memory and assign NULL to the pointer */
free(a);
a = NULL;
}
/* nothing bad will happen when we dereference b now */
printf("%p\n", *b);
/* nothing bad will happen when we free the memory region
where the pointer b points to points to */
free(*b);
}
答案 1 :(得分:1)
最好的选择是没有两个指针,指向同一个地方,它们是独立释放的 但如果这真的是你需要的,那么你需要一个引用计数。
以下代码实现了一个非常简单的引用计数机制
当您为数据指定第二个指针时,应使用clone_x
来增加引用计数
每次空闲时,使用free_x
,它只会释放一次。
请注意,此代码不是多线程安全的。如果您的代码是多线程的,那么您需要进行原子操作,并且需要非常小心地使用它们。
struct x {
int refcount;
int payload;
};
struct x *create_x(int payload) {
struct x *newx = malloc(sizeof(*newx));
if (!newx) return NULL;
newx->payload = payload;
newx->refcount = 1;
return newx;
}
void clone_x(struct x *myx) {
myx->refcount++;
}
void free_x(struct x *oldx) {
oldx->refcount--;
if (oldx->refcount == 0) {
free(oldx);
}
}
答案 2 :(得分:0)
你做不到。调用free(a)
时,访问该内存不再安全。
即使您malloc()
新内存并将结果分配给a
,该内存也可以在任何位置。
你要做的事情是行不通的。
答案 3 :(得分:0)
每个分配的内存块应该有一个'owner',a或b,如果a是所有者,指针b不应该释放该块,反之亦然。