1
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

4 回答 4

5

如果要确保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);
于 2013-05-10T07:09:26.187 回答
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);
    }
}
于 2013-05-10T08:14:57.343 回答
0

你不能。当free(a)被调用时,访问该内存不再安全。

即使您malloc()新建内存并将结果分配给a,该内存也可能在任何地方。

你试图做的事情不会奏效。

于 2013-05-10T06:59:45.523 回答
0

每个分配的内存块都应该有一个“所有者”,a 或 b,如果 a 是所有者,则指针 b 不应释放该块,反之亦然。

于 2013-05-10T08:05:02.673 回答