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

GTK C语言点击按钮修改多控件属性触发崩溃问题求助

问题根因
  • 回调函数签名不匹配:GTK 按钮clicked信号的标准回调函数必须包含两个参数,第一个是触发点击事件的按钮控件指针,第二个才是绑定信号时传入的自定义数据。当前回调函数只定义了一个参数,导致函数内拿到的data实际是按钮指针而非传入的app_data结构体,访问结构体成员时访问了非法内存,因此触发断言错误和段错误。
  • 结构体内存分配冗余(非崩溃核心原因):代码中用g_new0(AppData, 2)分配了2个AppData结构体的内存,实际只需要1个即可,属于可优化的代码问题。
修复方案
  1. 修改两个按钮点击回调函数的参数列表,补充第一个控件参数
  2. 修正AppData结构体的内存分配长度
  3. 补充结构体内存释放逻辑,避免内存泄漏
修复后可正常运行的代码
#include <gtk/gtk.h>

typedef struct AppData 
{
    GtkWidget *label1;
    GtkWidget *label2;
} AppData;

// 补充第一个参数:触发事件的控件指针
static void button1 (GtkWidget *widget, gpointer data)
{  
  AppData *data2 = (AppData*)data;
  gtk_widget_hide(data2->label1);
  gtk_widget_show(data2->label2);
}

// 补充第一个参数:触发事件的控件指针
static void button2 (GtkWidget *widget, gpointer data)
{
  AppData *data2 = (AppData*)data;
  gtk_widget_show(data2->label1);
  gtk_widget_hide(data2->label2);
}

int main(int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *fixed;
  
  GtkWidget *btn1;
  GtkWidget *btn2;
  
  GtkWidget *box1;
  GtkWidget *box2;
  
  gtk_init(&argc, &argv);
  
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "ethercat test 1");
  gtk_window_set_default_size(GTK_WINDOW(window), 1000,500);
  
  fixed = gtk_fixed_new();
  gtk_container_add(GTK_CONTAINER(window), fixed);
  
  box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 1);
  gtk_fixed_put(GTK_FIXED(fixed), box1, 0,0);
  
  box2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 1);
  gtk_fixed_put(GTK_FIXED(fixed), box2, 100,100);
  
  // 修正分配长度,只需要1个AppData结构体
  AppData *app_data = g_new0 (AppData, 1);

  app_data->label1 = gtk_label_new("label1");
  gtk_box_pack_start(GTK_BOX(box1),app_data->label1, TRUE,TRUE,0);
  
  app_data->label2 = gtk_label_new("label2");
  gtk_box_pack_start(GTK_BOX(box2),app_data->label2, TRUE,TRUE,0);
  
  btn1 = gtk_button_new_with_label("ethercat 1");
  gtk_fixed_put(GTK_FIXED(fixed), btn1, 10, 450);
  gtk_widget_set_size_request(btn1, 80,30);
 
  btn2 = gtk_button_new_with_label("ethercat 2");
  gtk_fixed_put(GTK_FIXED(fixed), btn2, 110, 450);
  gtk_widget_set_size_request(btn2, 80,30);

  gtk_widget_show_all(window);
  
  g_signal_connect(G_OBJECT(btn1), "clicked", G_CALLBACK(button1), app_data);
  g_signal_connect(G_OBJECT(btn2), "clicked", G_CALLBACK(button2), app_data);
  
  g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
  
  gtk_main();
  
  g_free(app_data);
  printf("program end\n");
  return (0);
  
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 13:54:04