我在函数中创建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()
(byatexit()
),当执行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()
是正确的(与我创建它时相同),并且当我通过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 *
的元素包含free_all()
内存,我应该如何释放这些元素的内存?标题部分:
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;
最佳答案
基本上,问题是您的clean_model
函数被传递到model**
而不是您期望的model*
。
记住GArray
是用来存储完整的结构,而不仅仅是指向结构的指针。为了做到这一点,它需要将结构的全部内容复制到内部data
数组中,因此指向结构的任何后续指针(传递给clean_model
)都将指向data
中的某个位置(即clean_model((elt_type*)&models->data[index * sizeof(elt_type)])
-在您的情况下elt_type
是model*
)
为了解决这种情况,我们想到了两种选择,按照(主观)偏好的顺序:
使用GPtrArray
代替;考虑到您的元素已经被动态分配了,内存管理/指针处理/类型转换(或者缺少)就不会那么混乱了
将clean_model
参数更改为model**
使用GArray
来存储model
结构而不是指针,但只有在可以将分配与填充模型内容(例如g_array_new(FALSE, FALSE, sizeof(model))
和fill_model(&g_array_index(models, model, i))
分开)分开时才有意义。
在所有情况下,您可能还应该将TRUE
传递给g_array_free
,因为您似乎没有在随后的任何事情中使用GArray.data
(这并不是说,如果您释放了其中所有有用的数据,那么这将没有任何意义)。
关于c - GArray元素的可用内存,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14684739/