我想將一個整數串列numbers傳遞給一個回呼函式printer,當一個按鈕被按下時,它將列印numbers的內容。這個論壇主題的最后一個帖子建議我這樣做:
#include <gtk/gtk.h>/span>
static void printer(GtkButton *button, gpointer user_data)
{
int *array = user_data;
g_print("%d %d %d %d %d
", array[0], array[1] 。array[2], array[3] 。array[4])。)
}
static void activate(GtkApplication *app, gpointer user_data)
{
GtkWidget *win;
GtkWidget *box;
GtkWidget *button;
//初始化數字。
int numbers[5] = {2, 3, 5, 7, 11}。
//window
win = gtk_application_window_new(GTK_APPLICATION(app))。
gtk_window_set_title(GTK_WINDOW(win), "Printer") 。
gtk_window_set_default_size(GTK_WINDOW(win), 80, 80) 。
// box; // box.
box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0) 。
gtk_window_set_child(GTK_WINDOW(win), box);
// button
button = gtk_button_new_with_label("Test")。
g_signal_connect(button, "clicked", G_CALLBACK(printer), (gpointer) numbers)。
gtk_box_append(GTK_BOX(box), button);
gtk_window_present(GTK_WINDOW(win))。
}
int main (int argc, char **argv) /span>
{
GtkApplication *app;
int status。
app = gtk_application_new("com.example.printer", G_APPLICATION_FLAGS_NONE) 。
g_signal_connect(app, "activation", G_CALLBACK(activation), NULL)。
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app)。
return status。
}
然而,當我嘗試執行這個程式時,程式輸出:
0 0 0 32583 0
如果回呼函式在列印前修改了陣列的內容,那么列印出來的結果將是正確的:
static void printer(GtkButton *button, gpointer user_data)
{
int *array = user_data;
array[0] = 3;
array[1] = 2;
array[2] = 1;
array[3] = 0;
array[4] = 1;
g_print("%d %d %d %d %d
", array[0], array[1] 。array[2], array[3] 。array[4])。)
}
這就像預期的那樣輸出3 2 1 0 -1。
我不確定為什么array[x]在兩種情況下都不同。這是推薦的將陣列傳入回呼函式的方式嗎?為什么array[x]在兩種情況下回傳不同的值?
uj5u.com熱心網友回復:
你傳遞給回呼函式的陣列地址是本地的激活函式。因此,當該回呼(后來)實際進行時,activate函式已經完成,并且指向的資料緩沖區(numbers)已經超出了范圍。因此,你有未定義的行為。
在你的案例中,該記憶體仍然可以被回呼例程訪問(但是不要依賴這一點),但是你在初始化中放置在那里的資料已經被覆寫了(被什么代碼部門和多少次覆寫,幾乎是不可能知道的,因為該記憶體可能在堆疊的某個地方)--因此你看到的是垃圾值。然而,當您在回呼函式(printer)中給出new值時,這些值將被正確顯示(但從技術上講,您仍然有未定義的行為,因為user_data所指向的記憶體may不再可用)。
解決這個問題的一個方法是使numbers陣列成為靜態,這樣當activate函式完成時,記憶體就會被保留下來:
static void activate(GtkApplication *app, gpointer user_data)
{
GtkWidget *win;
GtkWidget *box;
GtkWidget *button;
//初始化數字。
static int numbers[5] = {2, 3, 5, 7, 11}。//使 "靜態 "在呼叫后保留。
//...。
其他的選擇是。(a) 將numbers陣列作為一個全域變數(不是很好,而且經常被反對);(b) 使用malloc動態地分配陣列的記憶體(但當你用完后需要釋放該記憶體)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/306915.html
標籤:
上一篇:型別提示一個陣列
