使用 gtk_threads_add_timeout 时出现分段错误
Segmentation fault when using gtk_threads_add_timeout
我创建了一个非常简单的 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)
的第一个实例中,但是我遇到了分段错误。有人有任何类似的问题或有使用不同方法解决的类似用例吗?
在使用sprintf
之前,您需要为timeout
预留space:
这一行:
sprintf(timeout, "%d:%02d %s", hour, timeinfo->tm_min, "PM");
缓冲区的大小应足以包含整个结果字符串,但您使用的是未初始化的 char *
char *timeout;
应该是
char timeout[32]; // Some arbitrary size
我创建了一个非常简单的 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)
的第一个实例中,但是我遇到了分段错误。有人有任何类似的问题或有使用不同方法解决的类似用例吗?
在使用sprintf
之前,您需要为timeout
预留space:
这一行:
sprintf(timeout, "%d:%02d %s", hour, timeinfo->tm_min, "PM");
缓冲区的大小应足以包含整个结果字符串,但您使用的是未初始化的 char *
char *timeout;
应该是
char timeout[32]; // Some arbitrary size