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' 是否已被释放。
如果要确保free
对指向动态分配内存的指针的后续调用不会造成任何伤害,则应分配NULL
给该指针。因为(强调):
free() 函数释放 ptr 指向的内存空间,该内存空间必须由先前对 malloc()、calloc() 或 realloc() 的调用返回。否则,或者如果之前已经调用过 free(ptr),则会发生未定义的行为。如果 ptr 为 NULL,则不执行任何操作。
如果您想确保该指针b
将始终引用另一个指针所指向的同一对象a
,您可以b
改为指向的指针a
(并在每次需要使用它时取消引用它):
#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);
}
关于内存泄漏的另一件事。双重释放内存时不会有内存泄漏。在这种情况下,您将偶然发现未定义的行为,在这种情况下任何事情都可能发生。仅仅因为您不再(不再)访问不属于您自己的内存区域(参见这篇很棒的帖子)。相反,当您失去对动态分配内存块的引用时,您将泄漏内存。例如:
/* allocate some memory */
int *a = malloc(40);
/* reassign a without free-ing the memory before : you now have leaked memory */
a = malloc(40);
最好的选择是没有两个指针,指向同一个地方,它们是独立释放的。
但如果这确实是您需要的,那么您需要一个引用计数。
下面的代码实现了一个非常简单的引用计数机制。
当您为数据分配第二个指针时,您应该使用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);
}
}
你不能。当free(a)
被调用时,访问该内存不再安全。
即使您malloc()
新建内存并将结果分配给a
,该内存也可能在任何地方。
你试图做的事情不会奏效。
每个分配的内存块都应该有一个“所有者”,a 或 b,如果 a 是所有者,则指针 b 不应释放该块,反之亦然。