I have a thorny C syntax question. I'm building an array of linked lists, where each node in a list is represented by a struct. Each struct holds a string, which is important later:
// "linkedList.h"
typedef struct llnode listnode;
struct llnode {
char* data; // string
// ...and other data
};
My code builds a table of pointers to these "listnodes" and sets all those pointers to NULL, for reasons beyond the scope of this post:
void initTable(listnode** table){
// Initialize all pointers in the table to NULL
for (int i = 0; i < TABLESIZE; i++)
table[i] = NULL;
}
int main(){
// Create table of linked lists
listnode** table = (listnode**) malloc(TABLESIZE * sizeof(listnode*));
initTable(table);
return 1;
}
So far, so good. Later, my program stuffs data into the table, adding on to the right linked list if/when necessary. The code to do that works, but I'll offer up a HIGHLY simplified version here for the sake of keeping my post as brief as possible:
void insert(listnode** table, int index, char* newData){
if(*(table+index)==NULL){
// Create the new Node
listnode *newNode = NULL;
newNode = (listnode*)malloc(sizeof(listnode)); // allocate for the struct
newNode->data = (char*)malloc(sizeof(char)*15); // allocate for the string within the struct
strcpy(newNode->data, newData); // copy newData into newNode->data
// Insert node into table (Super simple version)
*(table+index) = newNode;
}
}
int main(){
listnode** table = (listnode**) malloc(TABLESIZE * sizeof(listnode*));
initTable(table);
insert(table, 0, "New String A");
insert(table, 5, "New String B");
insert(table, 7, "New String C");
return 1;
}
All this works great. Now for my real question... Suppose I want to reach into the table and dereference one of those strings?
void printTable(listnode** table){
for(int i=0; i<TABLESIZE; i++){
if(*(table+i)==NULL)
printf("table[%d] == NULL\n", i);
else
printf("table[%d] == %s\n", i, **(table+i)->data); // << PROBLEM IS HERE!
}
}
int main(){
// create & initialize the table, as above
// insert data into the table, as above
printTable(table);
return 1;
}
The compiler doesn't like my syntax:
$ gcc -Wall linkedList.c
linkedListc: In function ‘printTable’:
linkedList.c:31:48: error: request for member ‘data’ in something not a structure or union
printf("table[%d] == %s\n", i, **(table+i)->data);
^
$
So I know this is kinda a long-winding premise for a simple question, but can someone help me with the proper syntax here? I've tried a number of syntactical variations, with no luck.
More puzzling, when I modify the code a little to compile it, then look at this in GDB, I can see that **(table+i)
is my struct, yet **(table+i)->data
is not accessible. Here's the GDB output when I debug the (modified) program; the node representing "New String A" is inserted first at index 0 in the table. :
31 printf("table[%d] == %d\n", i, **(table+i));
(gdb) p *(table+i)
$1 = (listnode *) 0x6000397b0
(gdb) p **(table+i)
$2 = {data = 0x6000397d0 "New String A"}
(gdb) p **(table+i)->data
Cannot access memory at address 0x4e
(gdb)
I'm really confused about this. Once a C pointer goes through more than one layer of dereferencing, I start getting cross-eyed. Anyone know what the proper syntax here might be?
Thanks a million, -Pete
PS - Apologies for the superlong post. I swear I struggled to keep it a manageable size...