【发布时间】:2019-12-09 13:56:06
【问题描述】:
我正在尝试在 GCC 环境中为 C 库项目编写一个基本的内存管理系统,并来这里询问我所做的事情是否符合 C 标准。
基本上,我的代码库非常庞大,并且在代码中包含许多必需和非必需的 malloc 操作。并不是我如此粗心地将 malloc 放在我想要的任何地方,而是直到项目快结束时我才知道哪些值是必要的。
基本上我的计划是创建一个在翻译单元之间共享的全局引用计数器。并编写一个 malloc 包装器,该包装器递增并添加到此引用计数,并将指针存储在其中。所以剩下的就是在运行结束时释放循环中的所有引用。我在运行时的最后激活它,所以引用生命周期不是我要跟踪的问题,因此在某种程度上使问题变得更容易。
我还需要问这个重要的问题。我在代码中有很多类型的指针。所以在引用计数时,我必须将它们存储为void*,这会导致未定义的行为并产生问题吗?
编辑: These 值我指的是存储为 void* 是用 malloc 分配的常规指针(可能是 char*、int*、struct* 等...),并在代码中使用。但是鉴于引用计数器不知道这些类型,所以我计划将它们保存在void* 的列表中。
关于操作系统清理建议,不幸的是,我正在创建一个大型库库而不是可执行文件,因此即使我的代码结束运行,我也应该释放内存,这样库用户就不会遇到问题(用户的代码在调用我的库函数后没有结束,这就是为什么我不能依赖操作系统清理)
Edit2:让我们创建一个我打算做的小例子。
int ref_count = 0;
void* ref_list[64]; // 64 is arbitrary.
void* mallocWrapper(size_t size){
void* result = malloc(size);
ref_list[ref_count] = result;
ref_count += 1;
return result;
}
然后使用这个列表来释放代码中所有分配的内存。
【问题讨论】:
-
那么你的问题到底是什么?
-
您确定您的环境需要在运行时结束时释放所有内存资源吗?通常操作系统会清理分配所有内存资源的进程。
-
如果您创建了一个 minimal reproducible example 来展示您的想法,那就太好了
-
这里的XY香味很浓
-
对我来说听起来像是“使用 valgrind”(参见 valgrind.org)。
标签: c gcc memory-management