C语言GTK开发RGB选择器获取多range值触发段错误如何修复
问题原因
你代码触发段错误的核心原因是传入信号回调的Data结构体内存被提前释放:
你在activate函数中通过malloc申请了Data结构体的内存,并将该指针作为用户数据绑定到三个滑块的change-value信号上,但在activate函数结束前直接调用了free(data)释放了这块内存。
GTK的信号是异步触发的,activate执行完成后窗口才会开始响应用户操作,当你拖动滑块触发change-value信号时,传入回调函数的data指针已经是野指针,访问结构体成员自然会触发段错误。
修复方案
- 首先删除
activate函数末尾的free(data);语句,避免内存被提前释放。 - 绑定窗口销毁信号,在窗口关闭时自动释放
Data结构体内存,避免内存泄漏:
在activate函数中gtk_window_set_application之后添加如下代码:
g_signal_connect(window, "destroy", G_CALLBACK(free), data);
- (可选优化)修正
change-value信号的回调函数签名,避免参数不匹配引发潜在问题:
GTK的change-value信号默认回调原型包含3个前置参数,你当前的参数列表缺失两个,修改后的回调如下:
static gboolean changeLabel (GtkRange *range, GtkScrollType scroll, gdouble value, Data *data) { gdouble red = gtk_range_get_value(GTK_RANGE(data->redSlider)); g_print("%.0lf\n",red); // 不需要拦截信号传播时返回FALSE即可 return FALSE; }
补充说明
你调用g_object_unref(builder)后,从builder获取的控件指针依然有效:因为窗口会持有所有子控件的引用,只要窗口未被销毁,控件指针都可以正常访问。
内容的提问来源于stack exchange,提问作者Arkagedon
相关产品推荐
相关产品推荐

