g_array_free与g_array_unref有什么区别?分别应在什么场景使用?
g_array_free与g_array_unref的区别及适用场景 核心区别
两者都是GLib库中GArray类型的资源释放接口,核心差异在于是否遵循引用计数规则:
g_array_unref:严格遵循引用计数管理逻辑。每次调用会将数组的引用计数减1,只有当计数降到0时,才会自动释放GArray结构体、内部数据缓冲区,同时调用预先设置的元素清理函数释放每个元素的资源。g_array_free:忽略引用计数,直接执行释放操作。调用后会立即释放GArray结构体,是否释放内部数据缓冲区由传入的第二个free_segment布尔参数决定:参数为TRUE则同步释放缓冲区和清理元素,参数为FALSE则返回缓冲区指针,由调用者后续自行管理该内存的释放。
适用场景
应当使用g_array_unref的场景
只要你遵循GLib的引用计数规则使用GArray,都优先用这个接口:
- 你通过
g_array_new创建的数组,全程没有手动修改过引用计数,使用完直接调用g_array_unref即可自动清理所有资源 - 你曾经调用
g_array_ref为数组增加过引用计数,对应的减计数操作统一使用g_array_unref,避免手动管理导致的内存泄漏或野指针
示例:
// 创建数组,默认引用计数为1 GArray *arr = g_array_new(FALSE, FALSE, sizeof(int)); int val = 10; g_array_append_val(arr, val); // 使用完成,减引用计数到0,自动释放所有资源 g_array_unref(arr);
应当使用g_array_free的场景
只有当你确定自己是GArray的唯一持有者,且有以下需求时使用:
- 你需要提取GArray的底层数据缓冲区继续使用,不希望GLib释放这块内存,此时调用
g_array_free(arr, FALSE),返回的缓冲区指针后续需要你手动调用g_free释放 - 你不想用引用计数特性,确定没有其他位置持有该数组的引用,需要手动控制释放时机,可调用
g_array_free(arr, TRUE),效果等价于引用计数为1时调用g_array_unref
示例:
GArray *arr = g_array_new(FALSE, FALSE, sizeof(int)); int a = 1, b = 2; g_array_append_val(arr, a); g_array_append_val(arr, b); // 提取底层int数组,GArray结构体被释放,缓冲区不释放 int *data_buf = (int *)g_array_free(arr, FALSE); // 可以继续使用data_buf,用完手动释放 g_free(data_buf);
注意事项
- 调用
g_array_free后无论free_segment参数取值如何,都不要再次调用g_array_unref,否则会触发双重释放错误 - 如果有其他位置通过
g_array_ref持有该数组的引用,直接调用g_array_free会导致其他位置的数组指针变成野指针,引发崩溃
内容的提问来源于stack exchange,提问作者anton_rh
相关产品推荐
相关产品推荐

