M. *_*glu 4 c pointers memory-management dynamic-memory-allocation
我想将所有指向释放内存位置的指针设置为NULL,这样就不可能有悬空指针或双精度释放。这在C中可能吗?
例如,我具有以下结构:
struct B {
int *arr;
unsigned int len;
};
struct A {
struct B *b;
};
// Freeing and setting them to NULL:
bool test_safe_free() {
struct A *a = malloc(sizeof(struct A));
struct B *b = malloc(sizeof(struct B));
b->arr = malloc(100 * sizeof(int));
b->len = 100;
a->b = b;
safe_free_A(&a);
return a == NULL && b == NULL;
}
void safe_free_B(struct B **b_ref) {
if (*b_ref != NULL) free((*b_ref)->arr);
(*b_ref)->arr = NULL;
free(*b_ref);
*b_ref = NULL;
}
void safe_free_A(struct A **a_ref) {
// Before freeing A, freeing B:
if (*a_ref != NULL) safe_free_B(&((*a_ref)->b));
free(*a_ref);
*a_ref = NULL;
}
Run Code Online (Sandbox Code Playgroud)
该test_safe_free函数返回false,因为即使a在释放后将变量设置为NULL,b它仍指向已释放的内存,因为在a传递给函数时已复制了指针(副本设置为NULL,而原始副本保持不变)。。
我无法提出一种解决该问题的方法,但我也不确定我尝试做的事情是否可能。
C语言无法跟踪您对指针变量所做的所有复制。
C ++可以使用智能指针的概念来做到这一点,但是C不能,因为它没有类似于析构函数的功能。程序员要跟踪所有引用并适当地管理它们。
实现此目的的一种方法是实现引用计数,这不是一件容易的事。您将需要创建一个结构,该结构将充当所有分配的内存段的标头,其中包含当前引用计数。然后,您需要为malloc和家庭创建一个包装器,为头分配空间再加上请求的空间,在内存块的开始处写入头,然后在该块之后返回指向内存的指针。然后,您需要一个函数,该函数可以增加在创建新引用时手动调用的引用计数。然后,您需要一个函数来减少引用计数,该计数free在达到0时将调用。
当然,即使这样做,您也可以在知道何时不打电话free时记住记住在必要时增加/减少参考计数。递增失败表示使用已释放的内存和/或双重释放,而递减失败则表示内存泄漏。