By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,587 Members | 1,891 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,587 IT Pros & Developers. It's quick & easy.

Dynamic Allocation of an array/struct data structure

P: 3
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.
Dec 5 '06 #1
Share this Question
Share on Google+
4 Replies


P: 3
Sorry, diagram above didn't come out right this is what it should look like:
************u0>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>ui*** ***********************
***d0>>>>>>>>>>dj*******************************d0 >>>>>>>>>dj******************
*f0>>>fk**********f0>>>fk************************f 0>>>fk********f0>>>fk**************

Instead I'm getting this:

************u0>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>ui*** ***********************
***d0>>>>>>>>>>dj********************************* ***********************************
*f0>>>fk****************************************** ****************************************
Dec 5 '06 #2

DeMan
100+
P: 1,806
How do you iterate through the structs? I suspect you are not chnaging your pointer correctly between different instances of structs.

I also think your structurs should contain arrays of pointers to structs not the structs themselves (although I always manage to confuse myself when it comes to pointers....).
Dec 5 '06 #3

P: 3
Iterating through the structure depends on what you want to access, for example if you want to access a file permission you would use

SFS_Ptr->usernum[i].directorynum[j].filenum[k].file_permission

This can be done anywhere in the program. However, I can only get this to work with static arrays. When I try the dynamic implementation of it, it doesn't work. Could you possibly be more specific about arrays of pointers to structs? The struct pointing to a struct pointing to a struct works as long as you intialize it before compiling, however I don't know how to implement it dynamically. Like I said, in the struct's I changed
struct User usernum[10] to struct User* usernum
because you have to convert the array into a pointer if you want to allocate memory to it dynamically. However, I'm probably doing it wrong and I don't know what to do...
Dec 5 '06 #4

DeMan
100+
P: 1,806
declare, for example

Expand|Select|Wrap|Line Numbers
  1. struct User 
  2. {
  3.   char user_name[64];
  4.   int group_status;
  5.   struct *Directory directorynum[10];
  6. };
  7.  
and repeat this for the rest of the structs
you can alloctate the memory for each struct as you create it and should be able to do something like this:

usernum[i]->directorynum[j]->filenum[k]->file_permission
Dec 6 '06 #5

Post your reply

Sign in to post your reply or Sign up for a free account.