Passing an array to a function - Different values - Segfault

柔情痞子 提交于 2020-01-06 07:52:10

问题


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 gpointers 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!