我有一个结构,只包含我已分配的内存指针.有没有办法以递归方式释放每个指针而不是每个指针都是免费的?
例如,假设我有这样的布局:
typedef struct { ... } vertex;
typedef struct { ... } normal;
typedef struct { ... } texture_coord;
typedef struct
{
vertex* vertices;
normal* normals;
texture_coord* uv_coords;
int* quads;
int* triangles;
} model;
Run Code Online (Sandbox Code Playgroud)
在我的代码中我malloc每个结构创建一个模型:
model* mdl = malloc (...);
mdl->vertices = malloc (...);
mdl->normals = malloc (...);
mdl->uv_coords = malloc (...);
mdl->quads = malloc (...);
mdl->triangles = malloc (...);
Run Code Online (Sandbox Code Playgroud)
可以直接释放每个指针,如下所示:
free (mdl->vertices);
free (mdl->normals);
free (mdl->uv_coords);
free (mdl->quads);
free (mdl->triangles);
free (mdl);
Run Code Online (Sandbox Code Playgroud)
有没有办法可以递归迭代mdl中的指针而不是在每个元素上调用free?
(实际上,为每一个编写free()几乎没有任何工作,但它会减少代码重复并且对于学习有用)
Nat*_*ath 19
不是真的 - 虽然你可以写一个方法来做所有六个自由,这样你就不会错过一个.
void freeModel( model* md1 ) {
free (mdl->vertices);
free (mdl->normals);
free (mdl->uv_coords);
free (mdl->quads);
free (mdl->triangles);
free (mdl);
}
Run Code Online (Sandbox Code Playgroud)
在C语言中没有办法做到这一点,也不可能 - C不知道每个成员是通过malloc分配的不同指针,C不包含运行时类型信息支持来执行此操作 - 在运行时用于访问struct的已编译代码只是为每个成员访问使用基指针的偏移量.
最简单的方法是编写一个"FreeModel"函数:
void FreeModel(model* mdl)
{
free(mdl->vertices);
... // Other frees
free(mdl);
}
Run Code Online (Sandbox Code Playgroud)
这样的功能不是内置于C,但你可以通过滥用宏预处理器来作弊:
#define XX_MODEL_POINTERS do { \
xx(vertices); xx(normals); xx(uv_coords); xx(quads); xx(triangles); \
} while(0)
Run Code Online (Sandbox Code Playgroud)
分配:
model *mdl = malloc(sizeof(*mdl));
assert(mdl);
#define xx(N) mdl->N = malloc(sizeof(*mdl->N)); assert(mdl->N)
XX_MODEL_POINTERS;
#undef xx
Run Code Online (Sandbox Code Playgroud)
免费:
assert(mdl);
#define xx(N) free(mdl->N); mdl->NULL
XX_MODEL_POINTERS;
#undef xx
free(mdl);
mdl = NULL;
Run Code Online (Sandbox Code Playgroud)
令人讨厌的一点是,定义struct model和定义XX_MODEL_POINTERS会变得相互矛盾,而且无法捕捉它.因此,XX_MODEL_POINTERS通过在某处解析.h文件来生成定义通常会更好.
C中的元编程绝非易事.