我的代码中有这样的东西
typedef struct ts_fem_mesh
{
double **vertices;
unsigned int **triangles;
unsigned int n_ver;
unsigned int n_tri;
} fem_mesh;
fem_mesh *fem_mesh_new(unsigned int n_ver, unsigned int n_tri)
{
fem_mesh *mesh;
mesh = (fem_mesh *)malloc(sizeof(fem_mesh));
mesh->n_ver = n_ver;
mesh->n_tri = n_tri;
mesh->vertices = (double **)calloc(n_ver, sizeof(double *));
mesh->triangles = (unsigned int **)calloc(n_tri, sizeof(unsigned int *));
int i;
for(i=0;i<n_ver;i++)
mesh->vertices[i] = (double *)calloc(2, sizeof(double));
for(i=0;i<n_tri;i++)
mesh->triangles[i] = (unsigned int *)calloc(3, sizeof(unsigned int));
return mesh;
}
通常,当我致电fem_mesh_new
时,我会为n_ver
和n_tri
使用非常大的数字,这有时会导致分配错误(空间不足)。
即使我遇到这种错误,我的程序也应该建议用户并执行。
在这种情况下,我想释放自错误点以来我分配的所有东西(即当我尝试分配mesh->triangles
时出现错误,但mesh->vertices
被分配,所以我想释放{{1 }})
有更简单的方法吗?我能想到的唯一方法(这是我想要避免的那种方法)是填写我的代码 if(x == NULL) ,但这是非常烦人,因为内存的分配顺序(在我可能得到错误的每一点上,我都应该编写代码,释放从那时起分配的所有内容)。
不知道是否清楚,希望有人可以提供一些帮助:)
答案 0 :(得分:2)
您始终需要测试malloc()
的返回值。
我认为这是对goto
:
int foo(void) {
a = malloc();
if (!a) goto aerr;
b = malloc();
if (!b) goto berr;
c = malloc();
if (!c) goto cerr;
d = malloc();
if (!d) goto derr;
/* ... use memory ... */
free(d);
derr:
free(c);
cerr:
free(b);
berr:
free(a);
aerr:
return 0;
}
答案 1 :(得分:1)
由于动态分配在每次分配时都会失败,因此即使它很烦人,也应检查每次分配是否成功。但你只能在3分内完成:
在mesh = (fem_mesh *)malloc(sizeof(fem_mesh));
之后
在mesh->triangles = (unsigned int **)calloc(n_tri, sizeof(unsigned int *));
之后
并检查两个分配。
循环后,然后检查循环。