问题
I have the following code:
gpointer w[3];
GtkWidget *menu_item = gtk_menu_item_new();
w[0] = menu_item;
menu_item = gtk_menu_item_new();
w[1] = menu_item;
GtkTextBuffer *buffer = gtk_text_buffer_new(NULL);
w[2] = buffer;
This is all good till now. Let's now connect a signal:
g_signal_connect(w[0], "activate", G_CALLBACK(runner), w);
runner
function is declared as:
void runner(gpointer root, gpointer w[]);
Testing the values of w
array before entering runner
and while in it shows that they (the values) are different. I need them to be the same. How can I accomplish that, and why they aren't identical? Also, segfault occurs.
I created a small program that is bare bones of the original one and that is supposed to recreate the conditions such that the problem occurs. Oddly enough, it runs fine.
#include <gtk/gtk.h>
void carry(gpointer root, gpointer a[])
{
g_print("\n");
g_print("%d\n", root);
g_print("%d\n", a[0]);
g_print("%d\n", a[1]);
g_print("%d\n", a[2]);
}
int main(int argc, char **argv)
{
gtk_init(&argc, &argv);
GtkWidget *menu_item;
GtkTextBuffer *buffer;
gpointer abc[3];
menu_item = gtk_menu_item_new();
abc[0] = menu_item;
g_print("%d\t%d\n", menu_item, abc[0]);
menu_item = gtk_menu_item_new();
abc[1] = menu_item;
g_print("%d\t%d\n", menu_item, abc[1]);
buffer = gtk_text_buffer_new(NULL);
abc[2] = buffer;
g_print("%d\t%d\n", buffer, abc[2]);
g_signal_connect(abc[2], "modified-changed", G_CALLBACK(carry), abc);
gtk_text_buffer_set_modified(abc[2], TRUE);
gtk_main();
return 0;
}
Which means that something else is problematic. I'll try something else now, like commenting lines and leaving only the relevant ones.
I didn't comment any lines yet, but I tried putting
g_print
in both the caller and the callee.
This is an output:
1162863440 1162863440
1162864736 1162864736
1163320992 1163320992
1162863440
-2
1162668992
973486176
The first three lines compare the original values with their copies in the array (in the sense of g_print("%d\t%d\n", menu_item, abc[0]);
from the code above). As you can see, everything is assigned correctly. After a new line, we check those same values in the callee. root
, the first parameter, always has the correct value. So there's no problem with that. abc[0]
in the callee always has the value of -2. Seriously, every time I run the program it is -2. Other two (abc[1]
and abc[2]
) always have some garbage random values, but they change every time I run the program unlike abc[0]
.
I hope this will help in diagnosing and fixing the problem.
回答1:
I tried passing both abc[0]
and abc
normally through a function (func(arg0, arg1, ...)
instead of using g_signal_connect()
) and there is no problem whatsoever.
This all can mean only one thing: g_signal_connect
is messing with my values. It changes them for some unknown reason.
I guess I'll have to use a struct.
回答2:
You're not supposed to use gpointer
s everywhere. A gpointer
is a void *
, so you're pretty much disabling all the type checking the compiler could do for you. Use GtkWidget *
instead, and do proper casts using G_OBJECT()
, GTK_TEXT_BUFFER()
etc. macros.
You should also use typed callback arguments, as they appear in the documentation for each signal. For example for the activate
signal:
void
user_function (GtkMenuItem *menuitem,
gpointer user_data)
And if you want to pass several items in the user-data field, pass a pointer or pointer to a structure instead of an array of pointers.
And if you have a segfault, well, just use a debugger to check where the problem is.
来源:https://stackoverflow.com/questions/52212529/passing-an-array-to-a-function-different-values-segfault