两个指针指向相同的内存地址,如果在独立的地方释放这两个指针,如何避免内存泄漏?

时间:2013-05-10 06:55:57

标签: c pointers

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'是否已被释放。

4 个答案:

答案 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不应该释放该块,反之亦然。