无法将自定义用户数据结构体传递至GTK回调函数的问题求解
问题核心原因
你遇到的段错误是两个常见的GTK信号传参错误共同导致的:
- 信号绑定的用户数据传参类型错误
- 栈内存生命周期不匹配回调触发时机
具体错误分析与修复方法
1. 修正g_signal_connect的传参
你在make_buttons函数中接收的是结构体的指针,但绑定信号时直接传递了结构体本身的值,相当于把结构体的二进制内容强转成了指针地址,自然是非法的内存地址。
首先确认make_buttons的入参是指针类型,修改信号绑定代码:
// 假设make_buttons的函数签名为:GtkWidget *make_buttons(List_Store_Struct *list_store_struct_param) // 最后一个参数传入指针本身,而非结构体值 g_signal_connect(button, "clicked", G_CALLBACK(revert), list_store_struct_param);
2. 解决内存生命周期问题
你当前的List_Store_Struct是在函数栈上声明的,一旦声明该变量的函数执行完毕返回,对应的栈内存会被系统自动回收,后续回调触发时拿到的就是野指针,哪怕传参地址正确也会访问非法内存。推荐用堆分配的方式解决:
// 把原来的栈上声明改为堆内存申请,用GLib提供的g_new更安全 List_Store_Struct *list_store_struct = g_new(List_Store_Struct, 1); // 注意:必须正确初始化结构体的所有成员,避免空指针访问 list_store_struct->list_store_master = NULL; // 替换为你实际的初始化逻辑 list_store_struct->list_store_temporary = NULL; // 替换为你实际的初始化逻辑 list_store_struct->list_builder_struct = NULL; // 替换为你实际的初始化逻辑 // 传参时直接传递堆指针即可 GtkWidget *accounts_buttons_hbox = make_buttons(list_store_struct);
如果需要避免内存泄漏,可以绑定顶层窗口的destroy信号,在对应的回调中用g_free(list_store_struct)释放堆内存即可。
额外注意
结构体内部的指针成员(比如list_builder_struct)也要保证在回调触发时没有被提前释放,否则访问内部成员时仍会出现段错误。
内容的提问来源于stack exchange,提问作者9-Pin
相关产品推荐
相关产品推荐

