问题描述
假设我有2个指向同一对象的指针。
int * a = malloc(sizeof(int));
*a = 5;
int * b = a;
free(a);
a = NULL;
这时我知道a == NULL
,但b仍指向已释放的地址。是否有可能通过b知道内存已被释放?
这种情况是,我正在运行单元测试,并且要确保在正确的条件下在正确的时间释放某些结构,因此我想避免为了支持测试而添加基础结构。
解决方法
简短的回答:没有。长答案:绝对不是:-)
您可以实现一些技巧,例如使用双间接指针(包含指向实际后端数据的 pointer 的分配结构)(a),这基本上是智能指针在C ++中的工作方式,我在(b)之前已经在C中实现了它们。它们比原始指针要复杂得多,因为它们可能需要互斥锁保护的引用计数,并且所有仅的用法都通过API。
但是操纵这些指针的代码不一定是您的代码,因此,如果您将后端指针传递给某个函数,而该函数可以在没有指针的情况下释放它们,而无需通过您的 API,所有选择均关闭。另外,它为每次访问增加了额外的间接费用。
(a)一个简单的示例(不计算引用)是:
pointerA +---------------+ +-------------+
>---> | smart pointer | -> | actual data |
pointerB +---------------+ +-------------+
所有访问都是通过智能指针间接进行的,当pointerA
或pointerB
的 被“释放”时,可以将其设置为NULL。因此,如果您释放pointerA
,然后尝试使用pointerB
,则获得的值将为NULL。
这需要用于创建和销毁智能指针,获取和设置后端原始指针等等的API。
例如,
(b)GObject是在C中使用智能指针的部分引用计数变体。它构成了Gtk和GStreamer中对象模型的基础。>
Windows的早期版本, long ,在没有内存管理硬件的情况下处于保护模式之前(我在那透露年龄!)使用了类似的双重间接方案,因此它可以在将不会使所有进程都以无效的指针结束。