GArray元素的可用内存

时间:2013-02-04 10:25:11

标签: c linux free glib

我在我的函数中创建了drvm *drv结构。此结构本身包含包含malloc()-ed个字段(uint32_t *buffer)的字段。执行此操作的代码与此类似:

...
size_t elm_size = sizeof(model*);
uint32_t length = *(uint32_t*)len;

GArray *models = g_array_sized_new(FALSE, FALSE, elm_size, length);

model *mod;
for (int i = 0; i < length; ++i) {
    mod = create_model(...);
    g_array_append_val(models, mod);
}

这段代码不包含错误,经过高度测试。 在程序开始时,我注册函数free_all()(由atexit()),它应该在执行exit()时清理所有资源(特别是内存)。

在这个函数中,我正试图为elements of GArray*本身释放model *GArray *结构)内存:

GArray *models;
g_array_set_clear_func(models, clean_model);
if(!g_array_free(models, FALSE)) { //OK }

问题是当在clean_model(void *data)库中调用glib时,我建议它包含指向一个model *元素的指针。但地址错了,似乎没有任何正确的价值。既不GArray*也不model*

此外GArray *models函数中的free_all()是正确的(与我创建时相同)以及当我遍历GArray *中的所有free_all()元素时

for (int i = 0; i < len; ++i) {
    mod = g_array_index(models, model*, i); // Here I get correct pointer to model*
    clean_model(mod);
}

我得到了预期的值。

问题:出了什么问题?如果这些元素包含GArray *内存,我应该如何释放malloc()-ed元素的内存?

标题的一部分:

struct _info {
    uint32_t *buffer;
    uint32_t len;
};

typedef struct _info info;

struct _prod {
    uint32_t *buffer;
    uint32_t len;
};

typedef struct _prod prod;

struct _model {
    uint32_t name;
    prod product;
    info inform;
};

typedef struct _model model;

struct _drvm {
    GArray *models;
    GArray *strings;
};

typedef struct _drvm drvm;

1 个答案:

答案 0 :(得分:4)

基本上问题是您的clean_model函数已经过model**而不是您期望的model*

请记住,GArray旨在存储完整的结构,而不仅仅是指向结构的指针。为了做到这一点,它需要将结构的全部内容复制到内部data数组中,因此任何后续指向结构的指针(传递给clean_model)都是将指向data内的某个位置(即clean_model((elt_type*)&models->data[index * sizeof(elt_type)]) - 在您的情况下elt_typemodel*

为了解决这种情况,按照(主观)偏好的顺序会想到夫妻选择:

  1. 使用GPtrArray代替;鉴于您的元素已经动态分配,内存管理/指针处理/类型转换(或缺少它)将不那么混乱
  2. clean_model参数更改为model**
  3. 使用GArray存储model结构而不是指针,但只有在您可以将分配与填充模型内容分开时才有意义,例如: g_array_new(FALSE, FALSE, sizeof(model))fill_model(&g_array_index(models, model, i))
  4. 在所有情况下,您也应该将TRUE传递给g_array_free,因为您事后似乎没有使用GArray.data(不是因为它有任何意义)无论如何,你正在释放其中的所有有用数据。)