Dinamically allocate array of array of structures

V

valerio

Hello all
I would like to dinamically allocate an array of array of structures.
To explain this:

struct file{ char* fileName,int inode) myfiles[];
struct file{ char* fileName,int inode) mydirs[][];

but I would like to do it dinamically with linked list.
I am able to do it for myfiles, but not with mydirs.
Pseudo-code is ok.
If this is not so simple I will use static arrays.
Thanks a lot

Valerio
 
F

Frederick Gotham

valerio posted:
Hello all
I would like to dinamically allocate an array of array of structures.


I.e. a two-dimensional array of structures.

To explain this:

struct file{ char* fileName,int inode) myfiles[];
struct file{ char* fileName,int inode) mydirs[][];


Is this your first day learning C? Get the syntax right.

The amount of files in each directory will have to be constant:

#define FILES_PER_DIR 5
#define QUANTITY_DIRS 2

#include <stdlib.h>

typedef struct File {
char const *name;
} File;

File dir1[] = {{"a.exe"},{"b.exe"},{"c.exe"},{"d.exe"},{"e.exe"}};
File dir2[] = {{"a.bat"},{"b.bat"},{"c.bat"},{"d.bat"},{"e.bat"}};

File mydirs[QUANTITY_DIRS][FILES_PER_DIR];

int main(void)
{
unsigned i,j;
memcpy(mydirs,dir1,sizeof dir1);
memcpy(mydirs+1,dir2,sizeof dir2);

for(i=0; i!=QUANTITY_DIRS; ++i)
{
for(j=0; j!=FILES_PER_DIR; ++j)
{
puts(mydirs[j].name);
}
}

return 0;
}
 
K

Keith Thompson

valerio said:
I would like to dinamically allocate an array of array of structures.
To explain this:

struct file{ char* fileName,int inode) myfiles[];
struct file{ char* fileName,int inode) mydirs[][];

but I would like to do it dinamically with linked list.
I am able to do it for myfiles, but not with mydirs.
Pseudo-code is ok.
If this is not so simple I will use static arrays.

Linked lists and arrays are very different things. In a linked list,
each element is allocated separately, and the only way to get to an
element is to traverse all the elements leading up to it. It's a
useful technique if you don't know in advance how many elements you'll
need, but I suspect you really want an array.

The comp.lang.c FAQ is at <http://c-faq.com/>. Question 6.16 is
"How can I dynamically allocate a multidimensional array?". (I highly
recommend reading the rest of the FAQ as well, though perhaps not all
at one sitting.)
 
P

pete

valerio said:
Hello all
I would like to dinamically allocate an array of array of structures.
To explain this:

struct file{ char* fileName,int inode) myfiles[];
struct file{ char* fileName,int inode) mydirs[][];

but I would like to do it dinamically with linked list.

/* BEGIN list_of_lists.c output */

Person number 1
Initials: O.
Age : 32
Phone numbers:
163-4945
434-9890
785-6541
432-9672

Person number 2
Initials: B.L.
Age : 36
Phone numbers:
945-4349
890-7856
541-4329
672-3216

Person number 3
Initials: J.
Age : 24
Phone numbers:
349-8907

Person number 4
Initials: S.F.G.
Age : 24
Phone numbers:
907-8565
414-3296
723-2165
238-3036
381-0527

Person number 5
Initials: F.G.
Age : 20
Phone numbers:
565-4143
296-7232
165-2383

/* END list_of_lists.c output */

/* BEGIN list_of_lists.c */

#include <stdio.h>
#include <stdlib.h>

#define PEOPLE_MAX 5
#define NUMBERS_MAX 3
#define INITIALS 3
#define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define LU_RAND_SEED 123456789LU
#define LU_RAND(S) ((S) * 69069LU + 362437 & 0xffffffff)

struct list_node {
struct list_node *next;
void *data;
};

typedef struct list_node list_type;

struct person {
char name[2 * INITIALS + 1];
int age;
list_type *phone_numbers;
};

list_type *list_make(long unsigned count);
list_type *person_init(list_type *node, long unsigned seed);
list_type *number_init(list_type *node, long unsigned seed);
void make_name(char *name, size_t length, long unsigned seed);
void person_print(list_type *node);
void number_print(list_type *node);
void list_free(list_type *node, void (*free_data)(void *));
void person_free(void *data);

int main(void)
{
list_type *head;
long unsigned seed = LU_RAND_SEED;

puts("/* BEGIN list_of_lists.c output */");
head = list_make(1 + seed % PEOPLE_MAX);
if (head == NULL) {
fputs("No list\n", stderr);
}
seed = LU_RAND(seed);
if (person_init(head, seed) != NULL) {
person_print(head);
}
list_free(head, person_free);
puts("\n/* END list_of_lists.c output */");
return 0;
}

list_type *list_make(long unsigned count)
{
list_type *node, *list;

list = count != 0 ? malloc(sizeof *list) : NULL;
if (list != NULL) {
node = list;
while (--count != 0) {
node -> data = NULL;
node -> next = malloc(sizeof *node -> next);
if (node -> next == NULL) {
list_free(list, free);
return NULL;
} else {
node = node -> next;
}
}
node -> data = NULL;
node -> next = NULL;
}
return list;
}

list_type *person_init(list_type *node, long unsigned seed)
{
list_type *head;
struct person person;

head = node;
while (node != NULL) {
node -> data = malloc(sizeof person);
if (node -> data == NULL) {
fputs("person_init malloc problem\n", stderr);
head = NULL;
break;
}
seed = LU_RAND(seed);
make_name(person.name, INITIALS, seed);
seed = LU_RAND(seed);
person.age = 20 + seed % 20;
seed = LU_RAND(seed);
person.phone_numbers = list_make(1 + seed % PEOPLE_MAX);
if (person.phone_numbers == NULL) {
fputs("person.phone_numbers == NULL\n", stderr);
head = NULL;
break;
}
seed = LU_RAND(seed);
if (number_init(person.phone_numbers, seed) == NULL) {
fputs("person_init(person.phone_numbers, seed) == NULL\n",
stderr);
head = NULL;
break;
}
*(struct person *)node -> data = person;
node = node -> next;
}
return head;
}

list_type *number_init(list_type *node, long unsigned seed)
{
list_type *head;
size_t count;
char *string;

head = node;
while (node != NULL) {
node -> data = malloc(sizeof "xxx-xxxx");
if (node -> data == NULL) {
fputs("number_init malloc problem\n", stderr);
head = NULL;
break;
}
string = node -> data;
count = sizeof "xxx-xxxx" - 1;
while (count-- != sizeof "-xxxx" - 1) {
seed = LU_RAND(seed);
*string++ = (char)('0' + seed % 10);
}
*string++ = '-';
while (count-- != 0) {
seed = LU_RAND(seed);
*string++ = (char)('0' + seed % 10);
}
*string = '\0';
node = node -> next;
}
return head;
}

void person_print(list_type *node)
{
long unsigned count;
struct person *person;

for (count = 1; node != NULL; ++count) {
person = node -> data;
printf(
"\nPerson number %lu\n"
"Initials: %s\n"
"Age : %d\nPhone numbers:\n",
count, person -> name, person -> age
);
number_print(person -> phone_numbers);
node = node -> next;
}
}

void number_print(list_type *node)
{
while (node != NULL) {
printf(" %s\n", (char *)node -> data);
node = node -> next;
}
}

void make_name(char *name, size_t length, long unsigned seed)
{
length -= seed % length ;
while (length-- != 0) {
seed = LU_RAND(seed);
*name++ = UPPER[seed % sizeof UPPER];
*name++ = '.';
}
*name = '\0';
}

void list_free(list_type *node, void (*free_data)(void *))
{
list_type *next_node;

while (node != NULL) {
next_node = node -> next;
free_data(node -> data);
free(node);
node = next_node;
}
}

void person_free(void *data)
{
list_free(((struct person *)data) -> phone_numbers, free);
free(data);
}

/* END list_of_lists.c */
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,743
Messages
2,569,477
Members
44,898
Latest member
BlairH7607

Latest Threads

Top