我正在做一个学校项目,老师要求我们在项目结束时释放所有资源.

我正在努力寻找一种方法来编写更易读和/或更少的代码来管理这一点,特别是考虑到不同的出口点可能会有不同的资源集可供释放,这使得这一点变得更加复杂.

最简单、最混乱的解决方案似乎是这样(出口点表示为返回-1的"Some_sys_call"调用):

char *a = malloc(1);
if(some_sys_call() == -1){
   free(a);
   return -1;
}
//b is needed until the end
char *b = malloc(1);
if(some_sys_call() == -1){
   free(a);
   free(b);
   return -1;
}
//c is needed until the end
char *c = malloc(1);
//a is no longer needed from here on, so it's freed right away
free(a);
if(some_sys_call() == -1){
   free(b);
   free(c);
   return -1;
}
//Exit point when there are no errors
free(b);
free(c);
return 0;

这似乎不是很有吸引力,原因很明显:您需要编写大量代码,特别是当您拥有大量资源时,这会使代码变得过于臃肿,而且可读性较差. 当然,您不能简单地编写一个宏或函数来释放所有资源并在每个出口点调用它,如下所示:

#define free_all  free(a); \
                  free(b); \
                  free(c);

从技术上讲,您可以为每组自由定义不同的宏/函数:

#define free_1 free(a); 

#define free_2 free(a); \
               free(b);
...

这将使"实际"代码更具可读性,但仍需要您编写许多不同的宏,在我看来也不是一个好的解决方案.

这被认为是一个常见的问题吗?这通常是怎么处理的?

推荐答案

虽然这在很大程度上偏离了意见领域,但您可以实现一个链表数据 struct ,该 struct 保存指向已分配内存的指针,并在成功分配内存时添加它们.然后在失败时,您只需遍历该列表和每个指针free.

如果您使用映射,如果指针在程序的正常执行过程中被释放,则可以从映射中删除指针.

C++相关问答推荐

有效地计算由一组点构成的等边三角形和等腰三角形的数量

这是一个合法的C Strdup函数吗?

GLIBC:如何告诉可执行文件链接到特定版本的GLIBC

模拟shell并运行.sh文件

非常大的数组的大小

如何将常量char*复制到char数组

在Apple Silicon上编译x86的Fortran/C程序

用C++实现余弦函数

如何在VS 2022中正确安装额外的C头文件

在编写代码时,Clion比vscode有更多的问题指示器

如何用C语言为CLI应用程序编写按键检测系统?

将字符串数组传递给C中的函数:`str[dim1][str_size]`vs`*str[dim1]`

我在反转双向链表时遇到问题

试图创建一个基本的Word克隆,但遇到了障碍

Fscanf打印除退出C代码为1的程序外的所有内容

C中的char**v*char[]

如果类型是新的,offsetof是否与typeof一起工作?

我错误地修复了一个错误,想了解原因

如何在Rust中处理C的longjmp情况?

使用 SDL2 的 C 程序中的内存泄漏