Ошибка сегментации при использовании gtk_threads_add_timeout - PullRequest
1 голос
/ 02 апреля 2020

Я создал очень простой интерфейс GTK, который отображает время. Как таковой, его нужно будет часто обновлять, и после просмотра документов gtk_threads_add_timeout представляется логичным способом облегчить это. Я адаптировал функцию "set_time" для работы с функцией gtk и получил следующее:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>

#include <gtk/gtk.h>

typedef struct
{
  GtkWidget *label;
} time_args;

static int set_time(void *args);

int main (int argc, char *argv[])
{
    GtkBuilder *builder;
    GtkWidget *window;
    GtkLabel *time;
    time_args t_args;

    gtk_init(&argc, &argv);

    builder = gtk_builder_new();
    gtk_builder_add_from_file (builder, temp, NULL);

    window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));
    gtk_builder_connect_signals(builder, NULL);
    gtk_window_fullscreen(GTK_WINDOW(gtk_widget_get_toplevel(window)));

    time = GTK_LABEL(gtk_builder_get_object(builder, "time"));
    t_args.label = GTK_WIDGET(time);
    set_time(&t_args);
    gdk_threads_add_timeout(1000, set_time, &t_args);

    g_object_unref(builder);

    gtk_widget_show(window);
    gtk_main();

    return 0;
}

void on_window_main_destroy()
{
    gtk_main_quit();
}

static int set_time(void *args) {
    time_args *data = (time_args *)args;
    time_t rawtime = time(&rawtime);
    struct tm *timeinfo = localtime(&rawtime);
    char *timeout;
    int hour = timeinfo->tm_hour;

    if(hour > 12) {
        hour -= 12;
        sprintf(timeout, "%d:%02d %s", hour, timeinfo->tm_min, "PM");
    } else {
        sprintf(timeout, "%d:%02d %s", hour, timeinfo->tm_min, "AM");
    }

    gtk_label_set_text(GTK_LABEL(data->label), timeout);

    return G_SOURCE_CONTINUE;
}

Она прекрасно компилируется без предупреждений, а вызов set_time(&t_args) отлично работает при первом вызове, при первом экземпляр gdk_threads_add_timeout(1000, set_time, &t_args) однако я получаю ошибку сегментации. У кого-нибудь есть подобные проблемы или есть похожий вариант использования, который был решен с помощью другого метода?

1 Ответ

0 голосов
/ 02 апреля 2020

Вам необходимо зарезервировать место для timeout перед использованием sprintf:

В этой строке:

sprintf(timeout, "%d:%02d %s", hour, timeinfo->tm_min, "PM");

Размер буфера должен быть достаточно большим, чтобы вместить все результирующая строка, но вы используете неинициализированный char *

char *timeout;

bede

char timeout[32]; // Some arbitrary size
...