Reputation: 13
I am having issues passing structs (pointers) beyond the original function they were initialized in.
What I have noticed: The further I get from the function I originally initialized the struct in (as I pass the struct from one function to the next as a pointer), I basically start loosing the data (or reference to the data). When I try printing one of the integers in the struct and it will give me the correct value, then alternates into garbage (possibly mem location??), and then will print out the value again and garbage again randomly.
The program: In the following program I am trying to create a set of 5 Labels in which I can change the text of as I press an up or down button. The labels are attached to event boxes that, for now, prints the text of the labels onto the terminal. I am getting segmentation faults when trying to retrieve the text.
The result is I am getting seg faults when I try using the data in the struct (changing the text of labels within the struct, etc.)
struct Alpha{
GtkWidget *alphalbl[5]; //array of label widgets
gchar *alpha[38]; //array of characters
gint start; //start position
gint pos; //current position
};
void createWindow(GtkWidget *widget, gpointer data){
struct Alpha alpha; //Initialization of structure
/* Create window, layout, notebook, menu, etc*/
createList(&alpha, &layer) //layer is a struct of fixed layouts
}
The struct works in the following function:
void createList(gpointer structalpha, gpointer structlayers){
GtkWidget *alphaup, *alphadn;
GtkWidget *alphabox[5];
struct Layers *layer = structlayers;
struct Alpha *alphalist = (struct Alpha *)structalpha;
gchar *alphal[] = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9","<","[]"};
layer->fixedl = gtk_fixed_new();
for (int a = 0; a < 38; a++) //Add chararray to struct
alphalist->alpha[a] = g_strdup(alphal[a]);
alphalist->start = 0;
for(int i = 0; i < 5; i++){
alphalist->alphalbl[i] = gtk_label_new(alphalist->alpha[i]);
alphabox[i] = gtk_event_box_new();
gtk_widget_set_size_request(alphabox[i], 20, 20);
gtk_widget_set_name(GTK_WIDGET(alphabox[i]), g_strdup_printf("%d",i));
gtk_container_add(GTK_CONTAINER(alphabox[i]), alphalist->alphalbl[i]);
gtk_widget_set_events(alphabox[i], GDK_BUTTON_PRESS_MASK);
//g_signal_connect(alphabox[i], "button_press_event", G_CALLBACK(setLetter), (alphalist->alphalbl[i])); //originally tried sending just the single label
g_signal_connect(alphabox[i], "button_press_event", G_CALLBACK(setLetter), &alphalist); //<--struct does not send correctly
}
alphaup = gtk_button_new_with_label("^");
gtk_widget_set_size_request(alphaup, 50, 20);
g_signal_connect(alphaup, "clicked", G_CALLBACK(alphaUp), alphalist); //<--struct does not send correctly
alphadn = gtk_button_new_with_label("v");
gtk_widget_set_size_request(alphadn, 50, 20);
g_signal_connect(alphadn, "clicked", G_CALLBACK(alphaDown), alphalist); //<--struct does not send correctly
for(int y = 0; y < 5; y++)
gtk_fixed_put(GTK_FIXED(layer->fixedl), alphabox[y], 5, (50 + (y*15)));
}
The struct no longer works beyond (in setLetter). The "->" still finds the variables, but I get segmentation faults when I run the code unless I comment out the gtk_get_text... I have printed alphalist->start from this function only for it to work intermittently without changining its value. I have tried adding a '&' to alphalist in the callbacks without success.
void setLetter(GtkWidget *alphabox, gpointer alphal){
struct Alpha *alphalist = alphal;
gchar *charnum;
int num;
charnum = (gtk_widget_get_name(alphabox));
num = atoi(charnum);
g_print(gtk_label_get_text(GTK_LABEL(alphalist->alphalbl[num])));
g_free(charnum);
}
Is the issue that the memory isnt allocated correctly for the struct? Will calling malloc() solve my problem? If so where and how? I've tried adding it in without success. Any help will be greatly appreciated. Thank you in advance.
Upvotes: 0
Views: 468
Reputation: 13
Well, I did get a test program to work off of main. I'll have to modify it slightly to fit what I was doing earlier. Things to note are that when passing structs in the original program I would get compiler errors unless done with a gpointer. A function was previously here type error. Here it works perfectly fine. I also included a constructor for the struct. I will see if I can get the original modified and working. Thanks...
#include <gtk/gtk.h>
struct Alpha{
GtkWidget *label[5];
gchar *num[10];
gint start;
};
struct Alpha *Alpha_new(void){
struct Alpha *p = g_malloc(sizeof *p);
}
void Alpha_delete(struct Alpha *p, gpointer data){
g_free(p);
}
void createWindow(GtkWidget **window, struct Alpha *alpha, gint x, gint y);
void setLabel(struct Alpha *alpha, GtkWidget *button);
void printNum(struct Alpha *alpha);
void main(int argc, char** argv) {
GtkWidget *window;
struct Alpha *alpha;
alpha = Alpha_new();
gtk_init(&argc, &argv);
createWindow(&window, alpha, 600, 400);
gtk_widget_show_all(window);
gtk_main();
}
void createWindow(GtkWidget **window, struct Alpha *alpha, gint x, gint y){
GtkWidget *fixed, *label, *button;
gchar *num[] = {"0","1","2","3","4","5","6","7","8","9"};
*window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(*window), x, y);
fixed = gtk_fixed_new();
label = gtk_label_new("Struct Test");
gtk_fixed_put(GTK_FIXED(fixed), label, 280, 50);
button = gtk_button_new_with_label("TEST");
gtk_fixed_put(GTK_FIXED(fixed), button, 280, 250);
for(int y = 0; y < 10; y++)
alpha->num[y] = g_strdup(num[y]);
for(int a = 0; a < 10; a++)
g_print(alpha->num[a]);
g_print("----");
printNum(alpha);
for(int i = 0; i < 5; i++){
alpha->label[i] = gtk_label_new(alpha->num[i]);
gtk_fixed_put(GTK_FIXED(fixed), (alpha->label[i]), 310, (100 + (15*i)));
}
alpha->start = 1;
gtk_container_add(GTK_CONTAINER(*window), fixed);
g_signal_connect_swapped(button, "clicked", G_CALLBACK(setLabel), alpha);
g_signal_connect_swapped(*window, "destroy", G_CALLBACK(Alpha_delete), alpha);
}
void printNum(struct Alpha *alpha){
for(int i = 0; i < 10; i++)
g_print(alpha->num[i]);
}
void setLabel(struct Alpha *alpha, GtkWidget *button){
int start = alpha->start;
for(int i = 0; i < 5; i++){
if(i + start > 9)
gtk_label_set_text(GTK_LABEL(alpha->label[i]), alpha->num[(i + (start-10))]);
else
gtk_label_set_text(GTK_LABEL(alpha->label[i]), alpha->num[(i + start)]);
}
(alpha->start)++;
if(alpha->start == 10)
alpha->start = 0;
}
Upvotes: 1
Reputation: 2525
g_signal_connect(alphabox[i], "button_press_event", G_CALLBACK(setLetter), &alphalist); //<--struct does not send correctly
In createlist
alphalist
is pointer to struct Alpha. You try to pass a pointer to that, i.e. pointer to pointer to struct Alpha. That's a certain mistake, because this exact value is allocated on stack and is no longer valid when you return from createlist
.
If the first code block is not main
but a function, the same problem appears.
Upvotes: 0