c - 有没有办法将所有指向已释放内存的指针设置为 NULL?
问题描述
我想将所有指向已释放内存位置的指针设置为 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;
}
该test_safe_free
函数返回false,因为即使变量a
在释放后设置为NULL,b
仍然指向释放的内存,因为指针在a
传递给函数时被复制(并且副本设置为NULL,而原始保持不变) .
我想不出一种方法,一个结构来解决这个问题,但我也不确定我正在尝试做的事情是否可能。
解决方案
C 语言不会跟踪您对指针变量所做的所有副本。
C++ 可以通过智能指针的概念做到这一点,但是 C 不能,因为它没有类似于析构函数的功能。由程序员来跟踪任何引用并适当地管理它们。
一种方法是实现引用计数,这不是一件容易的事。您需要创建一个结构,该结构将充当所有已分配内存段的标头,这些内存段包含当前引用计数。然后,您需要为malloc
和系列创建一个包装器,为标题加上请求的空间分配空间,在内存块的开头写入标题,然后在块之后返回指向内存的指针。然后,您需要一个可以增加您在创建新引用时手动调用的引用计数的函数。然后你需要一个函数来减少引用计数,free
当它达到 0 时会调用它。
当然,即使你这样做了,你也需要知道何时不调用free
与记住在必要时增加/减少引用计数。递增失败意味着使用释放的内存和/或双重释放,而递减失败意味着内存泄漏。
推荐阅读
- javascript - 生产构建中的开发服务器编译问题和页面路由中断 - Next.js
- ios - 以编程方式 UITableView 中的自动调整标题和单元格
- python-3.x - Microsoft 认知服务 - 说话人识别 API - 验证 - 错误-SpeakerInvalid
- vue.js - 可以通过 DevTools 更改 vuex 状态吗?
- linux - linux kill() 在进程执行信号处理程序后返回吗?
- google-sheets - 如何提取“href”属性并将其粘贴到 Google 工作表中?
- sql-server - 在 gmail 服务器上使用 sp_send_dbmail 的 SQL Server 邮件发送错误
- android - 使用导航组件时从子级获取父级片段
- reactjs - 带有重定向的 React 中的 LoginPage
- c++ - CMakeLists.txt 中定义的测试目标的输出编译错误