通过多次分配处理函数中的清理

问题描述 投票:0回答:1

假设我有一个函数,它分配一些结构(对象),并且在设置其字段时必须分配额外的数据。由于每次分配都可能失败,因此对象创建可能只能部分成功。清理这个混乱的最常见方法是什么?我想最直接的事情是这样的:

struct Obj {
    struct ChildObj1 *child_obj1;
    struct ChildObj2 *child_obj2;
};

struct Obj *obj_create()
{
    struct Obj *obj = malloc(sizeof(struct Obj));
    if (!obj) {
        return NULL;
    }

    obj->child_obj1 = child_obj1_create();
    if (!obj->child_obj1) {
        free(obj);
        return NULL;
    }

    obj->child_obj2 = child_obj2_create();
    if (!obj->child_obj2) {
        free(obj->child_obj1);
        free(obj);
        return NULL;
    }

    return obj;
}

我觉得如果要创建很多对象,这可能会变得非常乏味。另外,当您稍后进行更改时,您可能很容易忘记更新“免费放松”。我正在考虑的另一种选择是利用我需要的“析构函数”,但要确保对结构进行零初始化。像这样:

struct Obj *obj_create()
{
    struct Obj *obj = malloc(sizeof(struct Obj));
    memset(obj, 0, sizeof(struct Obj));
    if (!obj) {
        return NULL;
    }

    obj->child_obj1 = child_obj1_create();
    if (!obj->child_obj1) {
        obj_destroy(obj);
        return NULL;
    }

    obj->child_obj2 = child_obj2_create();
    if (!obj->child_obj2) {
        obj_destroy(obj);
        return NULL;
    }

    return obj;
}

void obj_destroy(struct Obj *obj)
{
    if (!obj)
        return;

    if (obj->child_obj2)
        free(obj->child_obj2);

    if (obj->child_obj1)
        free(obj->child_obj1);

    free(obj);
}

这种做法有什么问题吗?还有其他更好的选择吗?

c memory-management constructor allocation
1个回答
0
投票

使用类似析构函数的函数接收指向对象的指针,释放可能与其相关的所有内容(如果已分配),最后释放对象本身。你也可以这样做:

if (
    (!(obj->child_obj1 = child_obj1_create())) ||
    (!(obj->child_obj2 = child_obj2_create()))
) {
    obj_destroy(obj);
    return NULL;
}
return obj;
© www.soinside.com 2019 - 2024. All rights reserved.