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

GTK4中多选时gtk_tree_selection_get_selected_rows返回NULL路径致崩溃

问题分析与修复方案

你的代码崩溃并非GTK4的bug,而是存在两个关键实现错误:

错误原因

  • GList访问方式错误:GList是GLib单向链表结构,不能通过selected_list[i]这种数组下标方式直接访问元素,这种写法会触发未定义行为,可能读取到NULL或错误内存地址。
  • 删除顺序导致路径失效:从前往后删除行时,每删除一行,GtkListStore中后续行的位置会自动前移。比如删除第0行后,原第1行变为新第0行,但你保存的TreePath仍指向原位置(路径值为1),此时用该路径获取迭代器会得到错误结果甚至NULL,最终引发段错误。

修复后的代码

static void delete_selected_rows(GtkButton *activated, GtkTreeView *tree_view) {
    GtkTreeSelection *tree_selection = gtk_tree_view_get_selection(tree_view);
    GtkTreeModel *model;
    GList *selected_list = gtk_tree_selection_get_selected_rows(tree_selection, &model);

    // 反转链表,从最后一行开始删除,避免路径失效
    GList *reversed_list = g_list_reverse(selected_list);

    for (GList *l = reversed_list; l != NULL; l = l->next) {
        GtkTreePath *path = l->data;
        GtkTreeIter iter;
        if (gtk_tree_model_get_iter(model, &iter, path)) {
            gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
        }
    }

    g_list_free(reversed_list);
    g_list_free_full(selected_list, (GDestroyNotify)gtk_tree_path_free);
}

修复说明

  1. 反转链表调整删除顺序:通过g_list_reverse()将选中路径链表反转,从最后一行开始删除,这样前面行的删除操作不会影响后续(当前遍历的)路径有效性。
  2. 标准GList遍历方式:使用GList原生的链表遍历逻辑访问元素,彻底规避数组下标访问的错误。
  3. 添加有效性检查:对gtk_tree_model_get_iter()的返回值做判断,即使路径意外失效也不会执行后续删除操作,进一步提升代码稳定性。

内容的提问来源于stack exchange,提问作者Fedor S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 11:40:33