-
Structs question
For a programming assignment I have the following two structs: (sorry it's a bit long!)
Code:
typedef struct Dir
{
char *name;
struct Dir** subDir;
struct Dir* parent;
struct
{
short r, w, x;
} Permissions;
} Directory;
typedef struct
{
Directory *currentDirectory;
int umask;
int time;
} Funix
I don't know if these structs are correct, but there have been no compilation errors so far. Here are some of the specifications for the program:
Code:
Directory struct contains
1. A dynamically allocated char* that holds its name.
2. A pointer to a dynamically allocated array of pointers to its immediate subdirectories
3. A pointer to its parent Directory.
If there are any errors with how I've used the structs please point it out! But my actual question is that I have to write a function called init(Funix *funix) that creates the currentDirectory (which should be named "/") and sets umask and time. This is the code in main() :
Code:
int main()
{
Funix *funix = (Funix*)malloc(sizeof(Funix));
run(funix);
free(funix);
}
I have run() call init() to set the umask and time, but I'm a little confused on how to create the currentDirectory ("/") since it seems like theres a struct within a struct or something. I'm sure this isn't that hard and I'm just being dumb, but I'm getting really confused with the structs. Any input is appreciated!
-
If subDir is to be an array of pointers, it needs to be struct dir **. That second struct you have listed doesn't have a name, unless it's Funix. You don't have a structure inside a structure; your second structure contains a pointer to an instance of the first structure. So you need to create a Directory for that pointer to point to.
-
Oh my bad, yeah it is Funix sorry.
So I first do Directory *currentDir? How would I access it? (*funix).currentDir.name? I havent seen that before, that's probably wrong.
thanks!
-
You could do (*funix).(*currentDirectory).name. Remember: (1) (*name).whatever is the same as name->whatever; (2) a pointer to an object is not the same thing as an object; just as the malloc gives your Funix pointer something to point at, you'll need to make a Directory for your Directory pointer to point at.
-
So if I understand you correctly I first have to do this in init()?:
Code:
Directory *currentDirectory = (Directory*)malloc(sizeof(Directory));
(*currentDirectory).name = (char*)malloc(sizeof(char));
The above works, but how do I associate this with my funix pointer? I tried this instead and it doesn't work:
Code:
(*funix).(*currentDirectory) = (Directory*)malloc(sizeof(Directory));
I think I just might be overlooking something.
-
You want (*funix).currentDirectory = malloc instead. (You're setting the pointer itself.)
-
Oh, I see, stupid mistake. Thanks
So it works now when I want to access the Funix struct (i.e. (*funix).umask = 666), but I still can't access the Directory struct. I tried this:
Code:
(*funix).(*currentDirectory).name = (char*)malloc(80*sizeof(char));
I get this error from g++ (we are supposed to use g++):
Code:
funix.c: In function 'void init(Funix*)':
funix.c:29: error: expected unqualified-id before '(' token
funix.c:29: error: 'currentDirectory' was not declared in this scope
make: *** [funix.o] Error 1
Any ideas?
Edit: This is the entire init() function so far...not very much:
Code:
void init(Funix *funix)
{
(*funix).currentDirectory = (Directory*)malloc(sizeof(Directory));
(*funix).(*currentDirectory).name = (char*)malloc(80*sizeof(char));
} //init()
-
Hmm. Does
Code:
funix->currentDirectory->name = (char*)malloc(80);
work?
-
Hm yes that does seem to work, what does it do exactly? Is there another way of doing this? I only remember learning a little bit about the -> operator a while ago, don't remember much now. thanks
-
If . is "member of", then -> is "member pointed to". I'm not going to try it, but
Code:
funix->currentDirectory->name
should actually correspond to
Code:
*((*funix).currentDirectory).name
that is, dereference funix, get currentDirectory as a pointer, dereference the whole thing, and then get name. It is now clear why -> was invented.
Edit: I lied. I tried it out, and it should be
Code:
(*(*funix).currentDirectory).name
instead.
-
Oh I see. I realize I made a mistake in my Directory struct though, the Permissions struct should not be defined in it like that, instead (I think) I want a pointer to an instance of the Permissions structure (just like the Funix struct contained a pointer to an instance of my Directory struct). I used the -> and everything seems to work so far but I'm still barely at the surface of this program.
Just want to say thanks though to tabstop for your quick responses and help, I'm actually further along than I expected to be at this point =]
-
Remember that malloc returns a pointer to your memory, so you need to assign it to a pointer! You mustn't dereference a pointer first and set it. Then you would get a segmentation fault.
And it's usually a bad idea to cast the result of malloc in C. You can see the FAQ on that.
-
Thanks Elysia, for the casting I learned to not cast it either, but for this assignment we are supposed to compile it with g++ (I'm not sure why exactly..) and I always get an error if I don't cast when using g++, so I figured you need to cast in C++ or something?
-
Yes, in C++ you need an explicit cast. That's entirely correct.
And, believe it or not, but it's great that you're compiling it as C++ code, because you're avoiding so many pitfalls present in C.
-
Ok so this isn't a structs question, but I've moved on to actually getting a command from the user. I want to store the number of arguments and also how many arguments. This is what I have now in function processCommand():
Code:
int processCommand(Funix *funix, char *command)
{
int i, j = 0, argCount = 0;
char *cmd, *str;
char **args;
cmd = strtok(command, " -");
while (str != NULL)
{
str = strtok(NULL, " -");
++argCount;
}
args = (char**)malloc(argCount*sizeof(int));
for(i = 0; i < argCount; i++)
args[i] = (char*)malloc(80*sizeof(char));
cmd = strtok(command, " -");
while (str != NULL)
{
str = strtok(NULL, " -");
strcpy(args[j], str);
j++;
}
return 0;
}
I get a segfault when using this, so obviously something is wrong but I can't find where. This is supposed to work like this: The first time I use strtok is simply to get a count for how many arguments there are. Then I want to dynamically create an array of strings (char **args) that's supposed to hold each argument of the command. So the second time I use strtok I actually want to store each argument into the array. I'm not sure where the error is here, maybe in my dynamically allocating the array of strings (args)?