Howdy folks,
I've been working on a c project, compiling using gcc, and I've reached a problem. The assignment requires creation of a two-level directory file system. No files have to be added or deleted, however it must be initialized by a function during run-time to contain so many users which each contain so many directories of which each contain so many files. I've completed the program and have it running flawlessly without implementing dynamic memory allocation with this data structure.
struct File
{
int file_permission;
};
struct Directory
{
char directory_name[64];
struct File filenum[10];
};
struct User
{
char user_name[64];
int group_status;
struct Directory directorynum[10];
};
struct Api
{
char api_name[64];
struct User usernum[10];
};
As you can see, all the struct arrays are initialized to 10. My problem is converting this to be initialized dynamically. Keep in mind, The initialization is only done with a function that only returns 0 on success and -1 on error. Additionally the only parameters in the function are the sizes of the arrays. So main looks something like this:
int main() {
sfs_init(5, 5, 5, 5);
return 0;
}
where it has the parameters sfs_int(int us, int ds, int fs, int gs);
us = number of users,
ds = number of directorys,
fs = number of files,
gs = number of groups.
Although I have groups implemented by a simple status int for each user. This is why I have a global variable setup as a pointer:
struct Api *SFS_Ptr;
In the function itself, I also intialize a struct Api:
sfs_int(int us, int ds, int fs, int gs); {
struct Api SFS;
To link the global pointer and the struct in the function i use:
SFS_Ptr = &SFS;
Then it's just a matter of initializing everything to the parameters:
for(i = 0; i < us; i++)
{ strcpy(SFS_Ptr->usernum[i].user_name, "u");
sprintf(buf1, "%d", i);
strcat(SFS_Ptr->usernum[i].user_name, buf1);
SFS_Ptr->usernum[i].group_status = 0;
for(j = 0; j < ds; j++)
{strcpy(SFS_Ptr->usernum[i].directorynum[j].directory_name, "d");
sprintf(buf2, "%d", j);
strcat(SFS_Ptr->usernum[i].directorynum[j].directory_name, buf2);
for(k = 0; k < fs; k++)
{ SFS_Ptr->usernum[i].directorynum[j].filenum[k].file_permission = 700;
}
}
}
The username and directory names get strcpy'd u0 or d0 respectively. The filename gets an int 700, which represents a file permission.
All of this works perfectly. Now how the heck can I implement this with dynamic memory allocation. I've come up with a partial solution but it probably just needs something very minor to work properly. So, the first thing I've done is change the arrays in the structs.
struct User usernum[10] to struct User* usernum
struct Directory directorynum[10] to struct Directory* directorynum
struct File filenum[10] to struct File* filenum
After doing this, I went in the function to add the mallocs like so:
SFS_Ptr->usernum = (struct User*) malloc(us * sizeof(struct User));
SFS_Ptr->usernum->directorynum = (struct Directory*) malloc(ds * sizeof(struct Directory));
SFS_Ptr->usernum->directorynum->filenum = (struct File*) malloc(fs * sizeof(struct File));
What does this produce? Not what was working before. Essentially, using printfs I've discovered that this does indeed allocate memory but it's not the way I want. This is the layout I need, and what I had working before:
u0 ...... ui
d0 ... dj d0 ... dj
f0...fk f0...fk f0...fk f0...fk
Instead I'm getting this:
u0 ...... ui
d0 ... dj
f0...fk
So it's mallocing the correct size for the files, directory, and users based on the parameters in the sfs_int(initialization function); however, it's completely killing the links between the different levels. For example if you scrolled backup and inserted a printf("DEBUG\n"); in the inner most for loop, running off variable k, which initializes the file_permission's to 700, after the actual initialization and you run the program you'd get:
DEBUG
DEBUG
DEBUG
DEBUG
DEBUG
Segmentation Fault
Because! The number of files in each directory is set to 5 and the struct array pointers are not pointing the files to any of the directories beyond the first one, as illustrated by the diagram above. Just like the directories are not pointed to any of the users beyond the first one, but this doesn't generate a problem for the user because there are no levels above the initial 5 users. So if anyone can possibly point me in the right direction I'd really appreciate it. I've experimented with the casting of the malloc numerous times with no success so I'm guessing this is a problem with the actual structure setup. Keep in mind nothing can be added to main other then the initializing function, and no parameters can be changed. Based on what I've had to relearn regarding pointers it seems like transforming the arrays into pointers is the right way to go in the structures but nothing goes indepth about handling this with arrays that point to arrays that point to arrays...
Thanks for your time, sorry for so much writing. You guys emphasize explaining hehe.