1

Can't figure out nested dereferencing for initializing a struct within a struct. I finally figured out initializing a struct through function calls for the Inode struct, but I can't seem to translate that to initializing a struct of structs through function calls for the Inodetable struct (which is a struct of Inode structs).

#include <stdio.h> #include <math.h> #include <stdlib.h> #include <string.h> int POINTERS_PER_INODE = 5; int Total_Inodes = 64; struct Inode { int valid;/* 0 == invalid, 1 == valid*/ int size; int Blocks [5]; }; struct InodeTable InodeTable; int InodeToString(char * InodeString, struct Inode iNode){ char * blockBuffer; sprintf(InodeString, "%d", iNode.valid); int i; for (i = 0; i < POINTERS_PER_INODE; i++){ blockBuffer = malloc(8); sprintf(blockBuffer, "%d", iNode.Blocks[i]); //no valid pointers yet strcat(InodeString,blockBuffer); free(blockBuffer); } return 0; } int initializeInode(struct Inode * iNode){ int i; for (i = 0; i < POINTERS_PER_INODE; i++){ iNode->Blocks[i] = -1; //no valid pointers yet } iNode->valid = 0; //initialized as invalid inode return 0; } int initializeInodeTable(struct InodeTable * ITable){ char * InodeTableString; char * inodeString; InodeTableString = malloc(sizeof(struct Inode) * 64); memset(InodeTableString, 0 , sizeof(struct Inode) * 64); for (int i = 0; i < Total_Inodes; i++){ inodeString = malloc(sizeof(struct Inode)); memset(inodeString, 0 , sizeof(struct Inode)); initializeInode(&ITable.InodeTable[i]); InodeToString(inodeString, &ITable.InodeTable[i]); strcat(InodeTableString,inodeString); free(inodeString); } printf("write: %s"InodeTableString); free(InodeTableString); return 0; } int main() { struct InodeTable iNodeTable[64]; initializeInodeTable(&iNodeTable); return 0; } 
5
  • "I'm having trouble" doesn't tell us specifically what your problem is. "Ive had to break it down and try to build it back up bit by bit" FYI, best practice is to always do it that way. It is not a good idea to write alot of code and then do a big bang test at the end. Write small bits of code, test that they work (ideally with auto unit tests) and then proceed to the next small bit of code. Commented May 14, 2020 at 23:41
  • specifically Im confused about nested dereferencing. it doesnt seem to work for a struct within a struct as it does for an array within a struct, I tried some variations of this with dereferencing arrows all over the place which didnt work, but maybe I got tripped up by the sprintf and just wasnt using the right combination? Commented May 14, 2020 at 23:44
  • I did originally write as much of the code in as small as possible chunks, but I had to adjust many parts when moving them from an IDE to the actual project which references files instead of just strings and then made changes to design decisions about the implementation of larger functions like importing files which changed how I planned to use/reference/read/write the user-defined structs. Commented May 14, 2020 at 23:49
  • I was able to initialize an inode struct by passing it into an initialization function, but when I try nesting that in an initialization function of an InodeTable which is a struct of the Inode structs and try to pass a pointer to an InodeTable in any of my best attempts at a similar manner, I can't seem to initialize anything. Commented May 14, 2020 at 23:57
  • The orginal project was much bigger and since I was making no headway on this initialization strategy, I built everything to avoid using the struct of structs, which helped me flesh out a lot of other design decisions and was the only alternative left since I couldnt figure this out, but its a clunky workaround that Im not pleased with, especially for adding future code and doesnt address my failure to implement the intended data structure. Commented May 15, 2020 at 0:11

1 Answer 1

1

Compiling your code with gcc (technically clang on mac) gives the following errors

Inode.c:52:30: error: member reference type 'struct InodeTable *' is a pointer; did you mean to use '->'? initializeInode(&ITable.InodeTable[i]); ~~~~~~^ -> Inode.c:52:30: error: incomplete definition of type 'struct InodeTable' initializeInode(&ITable.InodeTable[i]); ~~~~~~^ Inode.c:15:8: note: forward declaration of 'struct InodeTable' struct InodeTable InodeTable; ^ Inode.c:53:41: error: member reference type 'struct InodeTable *' is a pointer; did you mean to use '->'? InodeToString(inodeString, &ITable.InodeTable[i]); ~~~~~~^ -> Inode.c:53:41: error: incomplete definition of type 'struct InodeTable' InodeToString(inodeString, &ITable.InodeTable[i]); ~~~~~~^ Inode.c:15:8: note: forward declaration of 'struct InodeTable' struct InodeTable InodeTable; ^ Inode.c:59:23: error: expected ')' printf("write: %s"InodeTableString); ^ Inode.c:59:11: note: to match this '(' printf("write: %s"InodeTableString); ^ Inode.c:65:31: error: array has incomplete element type 'struct InodeTable' struct InodeTable iNodeTable[64]; ^ Inode.c:15:8: note: forward declaration of 'struct InodeTable' struct InodeTable InodeTable; ^ Inode.c:15:19: error: tentative definition has type 'struct InodeTable' that is never completed struct InodeTable InodeTable; ^ Inode.c:15:8: note: forward declaration of 'struct InodeTable' struct InodeTable InodeTable; ^ 7 errors generated. 

Therefore right off the bat, you should notice that you didn't define InodeTable. Maybe that's why you can't initialize the second struct.

Also, I think you meant to put * instead of &

*foo = "the data at the address foo"

and

&foo = "the address of the data foo"

another thing that needs to be fixed is you put

printf("write: %s" InodeTableString); 

as opposed to

printf("write: %s", InodeTableString); 

there is more than one argument if you use the syntax you were trying to use

also when accessing the member bar of a struct that is pointed to by foo it is good practice to use

foo->bar 

in other words

foo->bar = "the element bar from the struct that is pointed to by foo"

and you can avoid this whole "do I use * or & problem altogether" since the following is true

foo->bar = (*foo).bar

however, the following is a possible error

(*foo).bar != (&foo).bar

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks. I was using an IDE to visualize the code which has been helpful for tracking null terminators, but it doesnt give as much error info , so maybe Ill use gcc as well. The printf was a last minute typo that I didnt notice because of the error, I had previously been printing the individual inodes. Im a litle unsure about what you mean by define InodeTable since I assumed thats what "struct InodeTable InodeTable;" at the top and "struct InodeTable iNodeTable[64];" were doing and the rest was supposed to occur within the initialization function. what part of a proper definition am I missing?
oh dang! whoops! that first one was supposed to be: struct InodeTable{ struct Inode InodeTable[64]; }; and the second one: struct InodeTable iNodeTable;
still cant initialize though.
this: struct InodeTable iNodeTable; used to be struct Inode inode1; and I could pass that to the inode initialization correctly. I think I want to figure out how to declare each inode like that, without initializing it, inside the inodetable initialization, before passing it to the inode initialization. so before initializeInode would be something like: struct Inode *ITable->InodeTable[i]; except in a way that makes sense/compiles
I think what would help you the most is en.wikipedia.org/wiki/The_C_Programming_Language. This book was written by the creator of the C programming language (Ritchies) and one of the best expositors of computer science (Kernighan). It is affectionately called K&R and is considered to be mandatory reading in computer science culture. In section 6.5 they give an example of how to initialize a struct very similar to the one you are trying to write. See the talloc() function in that section which initializes a tnode struct which is part of a larger tree data structure structure.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.