GTK+ C:指针地址改变

GTK+ C: Pointer Address Changing

由于使用 GTK g_signal_connect.

时传递的指针的内存地址发生变化,我遇到了分段错误

这只发生在我的三台计算机中的一台上。它不工作的一台计算机是 运行 Arch Linux,所以我假设某些程序的版本领先于我的其他计算机,它们都是 运行 Fedora。我以为它是GTK+,所以我尝试降级,这没有任何影响。

奇怪...无论我在哪里编译程序,它总是在两台计算机上运行,​​而在一台上运行不正常,所以我认为这与编译器版本没有任何关系。

头文件:

typedef struct Timer {
  gboolean running;
} *TimerP;

typedef struct TimerData {
  TimerP timerPointer;
} *TimerDataP;

主要:

TimerP timerPointer;
timerPointer = malloc(sizeof(struct Timer));

TimerDataP timerDataP;
timerDataP = malloc(sizeof(struct TimerData));
timerDataP->timerPointer = timerPointer;

g_signal_connect (startButton, "clicked", G_CALLBACK (startTimerPressed), timerDataP);

startTimerPressed 函数:

static void startTimerPressed (GtkWidget *widget, gpointer data, TimerDataP timerData) {
    TimerP timer = timerData->timerPointer;
}

为了测试,我一直在定期执行此操作,这似乎在 main:

中无处不在
gpointer theGPointer;
startTimerPressed(startButton, theGPointer, timerDataP);

但是由于某种原因,当使用回调调用它时,内存位置发生了变化,里面的所有数据都乱七八糟,因此尝试访问任何内容都会导致分段错误。

请感谢您的帮助!

完整示例:

#include <stdio.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <time.h>
#include <cairo.h>
#include <stdlib.h>

typedef struct Timer {
  gboolean running;
}*TimerP;

typedef struct TimerData {
  TimerP timerPointer;
} *TimerDataP;

static void startTimerPressed (GtkWidget *widget, gpointer data, TimerDataP timerData) {
  printf("TimerData Location: %p\n", timerData);
  TimerP timer = timerData->timerPointer;
}

int main (int argc, char *argv[]) {
  GtkWidget *startButton;
  GtkWidget *window;
  GtkWidget *grid;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_default_size(GTK_WINDOW(window), 550, 200);
  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
  gtk_container_set_border_width (GTK_CONTAINER (window), 20);

  grid = gtk_grid_new();
  gtk_grid_set_column_spacing(GTK_GRID(grid), 20);
  gtk_grid_set_row_spacing(GTK_GRID(grid), 10);
  gtk_container_add (GTK_CONTAINER (window), grid);

  startButton = gtk_button_new_with_label ("Start");

  TimerP timerPointer;
  timerPointer = malloc(sizeof(struct Timer));

  TimerDataP timerDataP;
  timerDataP = malloc(sizeof(struct TimerData));

  printf("TimerData Location: %p\n", timerDataP);

  g_signal_connect (startButton, "clicked", G_CALLBACK (startTimerPressed), timerDataP);
  gtk_grid_attach (GTK_GRID (grid), startButton, 0, 4, 1, 1);

  gtk_widget_show_all(window);

  gtk_main ();
}

在我的两台电脑上,两个位置打印的内存位置相同,其中一台不同

static void startTimerPressed (GtkWidget *widget, gpointer data, TimerDataP timerData) {

gpointer data参数您传递给g_signal_connect()的数据。您要求的参数比 clicked 信号给您的要多。很遗憾没有办法检查信号函数参数:/你想要

static void startTimerPressed (GtkWidget *widget, TimerDataP timerData) {

static void startTimerPressed (GtkWidget *widget, gpointer data) {
    TimeDataP timerData = (TimerDataP) data;

相反。