You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用g_slist_copy_deep拷贝GSList出现段错误相关问题求助

段错误根因
  1. 对GCopyFunc的签名和参数含义理解错误
    GLib规定GCopyFunc的正确签名为 gpointer (*GCopyFunc) (gconstpointer src, gpointer user_data):
  • 第一个参数src是当前正在拷贝的原链表节点存储的数据指针,也就是你存入节点的Account*,不是GSList节点本身,更不是全局链表头。你将该指针强转为GSList*后访问->data属于非法内存访问,是段错误的直接原因。
  • 返回值是你拷贝生成的新数据指针,返回后g_slist_copy_deep会自动将其作为新链表对应节点的data,不需要手动添加到临时链表。
  1. 拷贝函数返回值类型错误
    你的代码将返回值写为GCopyFunc类型,和要求的gpointer完全不符,属于函数签名不匹配。
  2. 局部变量生命周期错误
    你定义的temporary_account是栈上局部变量,函数返回后内存会被回收,即使逻辑正确返回该地址也会造成野指针。
修正代码

正确的拷贝函数

gpointer account_copy(gconstpointer src, gpointer user_data) {
    // 直接强转为原数据类型Account*即可
    const Account* src_acc = (const Account*)src;
    // 堆内存分配新的Account对象,生命周期不受函数退出影响
    Account* new_acc = g_new(Account, 1);
    // 拷贝字段
    strcpy(new_acc->number, src_acc->number);
    strcpy(new_acc->description, src_acc->description);
    // 返回新对象指针,g_slist_copy_deep会自动处理节点添加逻辑
    return new_acc;
}

调用示例

GSList *master_account_list = read_account_numbers();
// 直接传入正确的拷贝函数即可,不需要强制类型转换
GSList *temporary_account_list = g_slist_copy_deep(master_account_list, account_copy, NULL);
注意事项
  • 临时链表使用完毕后需要用g_slist_free_full释放,避免内存泄漏:
// 第二个参数是每个节点data的释放函数,这里直接用g_free即可
g_slist_free_full(temporary_account_list, g_free);
  • 拷贝过程不需要手动遍历原链表、手动添加节点到新链表,这些逻辑g_slist_copy_deep内部已经全部实现。

内容的提问来源于stack exchange,提问作者9-Pin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 17:54:03