我试着用C语言做一个简单的GTK3窗口,当主程序发生错误时,它会显示一个错误消息,向用户显示发生了什么错误.但是,当我try 将gtk_main_quit函数连接到按钮时,GTK进程会抛出以下错误:

GLib-GObject-CRITICAL **: 16:04:36.787: instance with invalid (NULL) class pointer

GLib-GObject-CRITICAL **: 16:04:36.795: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed

然后,我被如何解决这个问题难住了.也许我没有正确初始化菜单?

我构造它的方式是通过一个全局 struct ,该 struct 在单独的函数中调用和分配,不会抛出任何错误.

以下是该函数的完整代码

int mensagem_erro()
 {
    GtkBuilder *construtor = NULL;

    printf("Alocando a janela...\n");
    construtor = malloc(sizeof construtor);

    alojar_erro();

    printf("Gerando a mensagem de erro...\n");
    snprintf(modelo_estrutura_erro->string_erro, TAMANHO_STRING_ERRO-1,"Erro! Erro n %i, 
    do tipo: %s", errno, strerror(errno));

    printf("Criando a tela de erro...\n");
    construtor = gtk_builder_new_from_file("tela_erro.glade");

    if(construtor==NULL)
    {
        printf("Erro! Erro n %i, do tipo: %s", errno, strerror(errno));
        return FALSE;
    }

    printf("Alocando os dados da tela de erro...\n");
    modelo_estrutura_erro->label_erro = GTK_LABEL(gtk_builder_get_object(construtor, 
    "label_erro"));

    if(modelo_estrutura_erro->label_erro==NULL){printf("Erro ao alocar a 
    estrutura!\n");return FALSE;}

    criar_widget(modelo_estrutura_erro->janela_erro, construtor,"janela_erro");
    criar_widget(modelo_estrutura_erro->box_erro, construtor,"box_erro");
    criar_widget(modelo_estrutura_erro->botao_erro, construtor,"botao_erro");
    printf("Inicializando os sinais da tela de erro...\n");
    g_signal_connect(GTK_WIDGET(modelo_estrutura_erro->botao_erro), "clicked", G_CALLBACK(gtk_main_quit),NULL);

    printf("Alocando a mensagem na tela de erro...\n");
    gtk_label_set_text(modelo_estrutura_erro->label_erro, modelo_estrutura_erro-                
    >string_erro);

    printf("Mostrando a janela de erro...\n");
    gtk_widget_show(modelo_estrutura_erro->janela_erro);

    g_object_unref(construtor);
    return TRUE;
}

推荐答案

这是错误的:

construtor = malloc(sizeof construtor);
  1. 您需要为sizeof *constructor而不是sizeof constructor预留空间,否则您将为指针预留空间.
  2. 将该行中保留的空间替换为malloc(内存泄漏):
construtor = gtk_builder_new_from_file("tela_erro.glade");

删除malloc行(相关:使用GTK/GLib时,始终首选安全版本g_malloc)

关于您的问题:

g_signal_connect(GTK_WIDGET(modelo_estrutura_erro->botao_erro), "clicked", G_CALLBACK(gtk_main_quit),NULL);

"clicked"事件与有效实例连接,clicked需要一个对象(而不是通用小部件)作为父对象.

GTK_WIDGET(modelo_estrutura_erro->botao_erro)替换为G_OBJECT(modelo_estrutura_erro->botao_erro).

C++相关问答推荐

传递给空闲的无效地址0x71 db7 cb5e0:未分配值

为什么复合文字(C99)的返回会生成更多的汇编代码?

有没有更简单的方法从用户那里获取数据类型来计算结果

堆栈帧和值指针

fwrite无法写入满(非常大)缓冲区

如何在C中引发/处理自定义信号?

C-使用指针返回修改后的整数数组

使用错误的命令执行程序

I2C外设在单次交易后出现故障

等同于铁 rust 的纯C语言S未实现!()宏

在C中访问数组中的特定值

为什么电路板被循环删除?

使用Open62541向OPCUA服务器发送读请求时内存泄漏

如何组合两个宏来初始化C语言中的字符串数组?

是否有单独的缓冲区用于读写库调用?

在下面的C程序中,.Ap0是如何解释的?

Linux/C:带有子进程的进程在添加waitid后都挂起

传递给函数的 struct 中的数组

如何编写postgresql支持函数

当读取可能会阻塞管道中的父进程时,为什么要等待子进程?