Velocity Reviews > Array of Structures

# Array of Structures

Sam
Guest
Posts: n/a

 05-02-2006
Hello I have a structure called Company.

struct Company
{
char *employee;
};

I want to build an array of this structure but the number of employees
will change thorughout the course the programs use so it will need to
be dynamic.

I know I need to first allocate the structure and then allocate the
array of structures but I am confussed on how to do this.

In my program I am doing the following

Also for right now I am using

#Define count = 100; until I get the count function setup properly to
get the exact count in the future

void u_setup_company_array(int employee_number)
{
int q;
struct Company CompArray;

/*Allocate the array structure */
CompArray= (struct Company ) malloc(count* sizeof(struct Company
*));

/*if bad allocation then return */
if(!CompArray)
{
return;
}

/*allocate the array and set the variables to Null */
for(q = 0; q<= count ; h++)
{
CompArray[q] = (struct Company ) malloc(sizeof(CompArray));
CompArray[q]->employee= NULL;
}

/*Once the array is allocated then I pass it and the employee
number to the other function */
status = build_company_array(employe_number, CompArray);

In another module I would have the function build_company_array

long build_company_array(int employee_number, structure CompArray)
{
/* Read the database and find a match on the employee number */
int counter = 0;
while (database_emp#)
{

if (database_emp# == employee_number)
{
CompArray[count]employee = getName(employee_number);
counter++;
}
}
return 0;
}

I guess my questions pertain to proper allocation of the structure and
the array. It's a simple straight forward structure so I don't think I
need to make it a pointer to a structure do I?

Anyway

1) Am I defining my structure properly in my initial function? Should
it be struct Company CompArray; or struct Company *CompArray;

2) Am I allocating the structure properly?
3) Am I allocating the array properly?
4) Am I passing the array properly so that when it returns it will be
populated with the right values that it built in the called function?

What I want to do is setup the array in the first u_setup_company_array
function pass the allocated array to the build_company_array function
in the other module. Once in the other module I populate it. When it
comes returns to the u_setup_company_array function then it will be
populated and ready for use in the next step of the
u_setup_company_array function

Once done with everything in the array then I would get rid of it which
i understand what to do there.

can you guys help?

Thanks
Sam

BTW I am using using c modules compiled in Visual Studios.Net

liorm
Guest
Posts: n/a

 05-02-2006
You have implemented CompArray as an array of pointers to Company
(struct type), so CompArray should be declared as struct Company
**CompArray. Pointer to pointer is actually array of pointers. I don't
see any other issues with your code except for that.

LM

pete
Guest
Posts: n/a

 05-02-2006
Sam wrote:
>
> Hello I have a structure called Company.
>
> struct Company
> {
> char *employee;
> };

> It's a simple straight forward structure so I don't think I
> need to make it a pointer to a structure do I?

I don't know what you mean.

/* BEGIN new.c output */

Fred
11 Maiden Lane

/* END new.c output */

/* BEGIN new.c */

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

#define COUNT 100

struct Company {
char *employee;
};

void free_CompArray(struct Company *CompArray, size_t index);

int main(void)
{
struct Company *CompArray;
size_t index;
int random;

CompArray = malloc(COUNT * sizeof *CompArray);
if (CompArray == NULL) {
puts("CompArray == NULL");
exit(EXIT_FAILURE);
}
for (index = 0; index != COUNT; ++index) {
CompArray[index].employee = NULL;
}
random = rand() % COUNT;
CompArray[random].employee = malloc(sizeof "Fred");
if (CompArray[random].employee == NULL) {
puts("CompArray[random].employee == NULL");
exit(EXIT_FAILURE);
}
= malloc(sizeof "11 Maiden Lane");
exit(EXIT_FAILURE);
}
strcpy(CompArray[random].employee, "Fred");
puts("/* BEGIN new.c output */\n");
puts(CompArray[random].employee);
free_CompArray(CompArray, COUNT);
puts("\n/* END new.c output */");
return 0;
}

void free_CompArray(struct Company *CompArray, size_t index)
{
const size_t count = index;

for (index = 0; index != count; ++index) {
free(CompArray[index].employee);
}
free(CompArray);
}

/* END new.c */

--
pete

Keith Thompson
Guest
Posts: n/a

 05-02-2006
"liorm" <(E-Mail Removed)> writes:
> You have implemented CompArray as an array of pointers to Company
> (struct type), so CompArray should be declared as struct Company
> **CompArray. Pointer to pointer is actually array of pointers. I don't
> see any other issues with your code except for that.

see how and why.

No, a pointer to pointer is not actually an array of pointers. Arrays
are not pointers; pointers are not arrays. Please read section 6 of
the comp.lang.c FAQ, <http://www.c-faq.com/>.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

CBFalconer
Guest
Posts: n/a

 05-03-2006
Sam wrote:
>
> Hello I have a structure called Company.
>
> struct Company
> {
> char *employee;
> };
>
> I want to build an array of this structure but the number of
> employees will change thorughout the course the programs use so
> it will need to be dynamic.

The structure would be better labelled "anemployee". At any rate,
the important thing is what sort of operations do you need to
perform on these things? Which have to be fast? Which just have
to be feasible? What items are you likely to add or remove? You
will probably find that an array is not the right thing to hold the
collection.

I suspect you will find that a hash table will do all you want.
There is one available under GPL at:

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the

Sam
Guest
Posts: n/a

 05-03-2006
Hello everybody base upon the information that I got from you guys I

struct EmpInfo
{
char *employee;
};

void u_setup_empinfo_array(int employee_number)
{
int q;
struct EmpInfo *EmpArray;

count = u_emp_count(employee_number); <--- Counter comes back with
500
employees from a read on the database count where the
employee numbers
match
if(!count)
{
return;
}

/*Allocate the array structure */
EmpArray= malloc(count * sizeof *EmpArray);

if(!EmpArray)
{
return;
}

for(q = 0; h< count ; q++)
{
EmpArray[q]->employee= NULL;
}

/*Get the array of employee info*/
status = build_empinfo_array(employee_number, EmpArray)

if(status)
{
for(h = 0; h< count ; h++)
{
free(EmpArray[q]->employee);
}
free(cm8tablename);
return;
}
else
{
.......do something with it the array
}

/*Clean up the array - no longer need it */
for(h = 0; h< count ; h++)
{
free(EmpArray[q]->employee);
}
free(cm8tablename);
return
}

long build_empinfo_array(int employee_number, EmpInfo *EmpArray)
{
int count = 0;
while (database_emp#)
{

if (database_emp# == employee_number)
{
EmpArray[count]employee = (char
*)malloc(sizeof(getName(employee_number)));
EmpArray[count]employee = getName(employee_number);

(employee_number)));
count++;
}
}
return 0;
}

u_emp_count(int employee_number)
{
int count = 0;
while (database_emp#)
{

if (database_emp# == employee_number)
{
count++;
}
}
return count;
}
The arrary comes back to the calling function and the array appears to
be built correctly with the name and the address of the employee

The problem that when I am done with the array I want to clear it and
free it but it crashes on the first line of the clean

/*Clean up the array - no longer need it */
for(h = 0; h< count ; h++)
{
free(EmpArray[q]->employee); <-------------------- crashes
here
}
free(cm8tablename);

Ass I said the array looks to have been built correctly and you can see
that prior to the data being placed in the employee variable it is
malloc'ed with the size of what it gets back from the call. Then I do
the same call to just get the data into the variable. Something tells
me that I am still not allocating something properly but what - Advice?

Thanks
Sam

pete wrote:
> Sam wrote:
> >
> > Hello I have a structure called Company.
> >
> > struct Company
> > {
> > char *employee;
> > };

>
> > It's a simple straight forward structure so I don't think I
> > need to make it a pointer to a structure do I?

>
> I don't know what you mean.
>
> /* BEGIN new.c output */
>
> Fred
> 11 Maiden Lane
>
> /* END new.c output */
>
>
> /* BEGIN new.c */
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>
> #define COUNT 100
>
> struct Company {
> char *employee;
> };
>
> void free_CompArray(struct Company *CompArray, size_t index);
>
> int main(void)
> {
> struct Company *CompArray;
> size_t index;
> int random;
>
> CompArray = malloc(COUNT * sizeof *CompArray);
> if (CompArray == NULL) {
> puts("CompArray == NULL");
> exit(EXIT_FAILURE);
> }
> for (index = 0; index != COUNT; ++index) {
> CompArray[index].employee = NULL;
> }
> random = rand() % COUNT;
> CompArray[random].employee = malloc(sizeof "Fred");
> if (CompArray[random].employee == NULL) {
> puts("CompArray[random].employee == NULL");
> exit(EXIT_FAILURE);
> }
> = malloc(sizeof "11 Maiden Lane");
> if (CompArray[random].employee_address == NULL) {
> exit(EXIT_FAILURE);
> }
> strcpy(CompArray[random].employee, "Fred");
> puts("/* BEGIN new.c output */\n");
> puts(CompArray[random].employee);
> free_CompArray(CompArray, COUNT);
> puts("\n/* END new.c output */");
> return 0;
> }
>
> void free_CompArray(struct Company *CompArray, size_t index)
> {
> const size_t count = index;
>
> for (index = 0; index != count; ++index) {
> free(CompArray[index].employee);
> }
> free(CompArray);
> }
>
> /* END new.c */
>
>
> --
> pete

Sam
Guest
Posts: n/a

 05-03-2006
Hello everybody base upon the information that I got from you guys I

struct EmpInfo
{
char *employee;
};

void u_setup_empinfo_array(int employee_number)
{
int q;
struct EmpInfo *EmpArray;

count = u_emp_count(employee_number); <--- Counter comes back with
500
employees from a read on the database count where the
employee numbers
match
if(!count)
{
return;
}

/*Allocate the array structure */
EmpArray= malloc(count * sizeof *EmpArray);

if(!EmpArray)
{
return;
}

for(q = 0; h< count ; q++)
{
EmpArray[q]->employee= NULL;
}

/*Get the array of employee info*/
status = build_empinfo_array(employee_number, EmpArray)

if(status)
{
for(h = 0; h< count ; h++)
{
free(EmpArray[q]->employee);
}
free(cm8tablename);
return;
}
else
{
.......do something with it the array
}

/*Clean up the array - no longer need it */
for(h = 0; h< count ; h++)
{
free(EmpArray[q]->employee);
}
free(cm8tablename);
return
}

long build_empinfo_array(int employee_number, EmpInfo *EmpArray)
{
int count = 0;
while (database_emp#)
{

if (database_emp# == employee_number)
{
EmpArray[count]employee = (char
*)malloc(sizeof(getName(employee_number)));
EmpArray[count]employee = getName(employee_number);

(employee_number)));
count++;
}
}
return 0;
}

u_emp_count(int employee_number)
{
int count = 0;
while (database_emp#)
{

if (database_emp# == employee_number)
{
count++;
}
}
return count;
}
The arrary comes back to the calling function and the array appears to
be built correctly with the name and the address of the employee

The problem that when I am done with the array I want to clear it and
free it but it crashes on the first line of the clean

/*Clean up the array - no longer need it */
for(h = 0; h< count ; h++)
{
free(EmpArray[q]->employee); <-------------------- crashes
here
}
free(cm8tablename);

Ass I said the array looks to have been built correctly and you can see
that prior to the data being placed in the employee variable it is
malloc'ed with the size of what it gets back from the call. Then I do
the same call to just get the data into the variable. Something tells
me that I am still not allocating something properly but what - Advice?

Thanks
Sam

pete wrote:
> Sam wrote:
> >
> > Hello I have a structure called Company.
> >
> > struct Company
> > {
> > char *employee;
> > };

>
> > It's a simple straight forward structure so I don't think I
> > need to make it a pointer to a structure do I?

>
> I don't know what you mean.
>
> /* BEGIN new.c output */
>
> Fred
> 11 Maiden Lane
>
> /* END new.c output */
>
>
> /* BEGIN new.c */
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>
> #define COUNT 100
>
> struct Company {
> char *employee;
> };
>
> void free_CompArray(struct Company *CompArray, size_t index);
>
> int main(void)
> {
> struct Company *CompArray;
> size_t index;
> int random;
>
> CompArray = malloc(COUNT * sizeof *CompArray);
> if (CompArray == NULL) {
> puts("CompArray == NULL");
> exit(EXIT_FAILURE);
> }
> for (index = 0; index != COUNT; ++index) {
> CompArray[index].employee = NULL;
> }
> random = rand() % COUNT;
> CompArray[random].employee = malloc(sizeof "Fred");
> if (CompArray[random].employee == NULL) {
> puts("CompArray[random].employee == NULL");
> exit(EXIT_FAILURE);
> }
> = malloc(sizeof "11 Maiden Lane");
> if (CompArray[random].employee_address == NULL) {
> exit(EXIT_FAILURE);
> }
> strcpy(CompArray[random].employee, "Fred");
> puts("/* BEGIN new.c output */\n");
> puts(CompArray[random].employee);
> free_CompArray(CompArray, COUNT);
> puts("\n/* END new.c output */");
> return 0;
> }
>
> void free_CompArray(struct Company *CompArray, size_t index)
> {
> const size_t count = index;
>
> for (index = 0; index != count; ++index) {
> free(CompArray[index].employee);
> }
> free(CompArray);
> }
>
> /* END new.c */
>
>
> --
> pete

Guest
Posts: n/a

 05-04-2006
Sam wrote:
> Hello I have a structure called Company.
>
> struct Company
> {
> char *employee;
> };

struct employee
{
char *name;
};

The point is that your nomenclature should not be misleading to the code

> I want to build an array of this structure but the number of employees
> will change thorughout the course the programs use so it will need to
> be dynamic.

Here are some choices:
1. array declared with fixed size (simplest)
2. array allocated at run time with size which doesn't change after
allocation (malloc/calloc)
3. array allocated at run time that can vary during execution (malloc +
realloc)
4. dynamic list or tree structure (dynamic allocation with pointers

> I know I need to first allocate the structure and then allocate the
> array of structures but I am confussed on how to do this.

No. If you allocate an array of structures, you don't need to allocate
individual structures.

> In my program I am doing the following
>
> Also for right now I am using
>
> #Define count = 100; until I get the count function setup properly to
> get the exact count in the future

That's
#define count 100

> void u_setup_company_array(int employee_number)
> {
> int q;
> struct Company CompArray;
>
> /*Allocate the array structure */
> CompArray= (struct Company ) malloc(count* sizeof(struct Company
> *));

If you want to allocate the array at run time, you need to declare a
pointer to the structure:
struct employee *CompArray;

Your allocation will work. The canonical form recommended in this forum is
CompArray = malloc (count * sizeof (*CompArray));

Using a pointer to the destination pointer as the sizeof operand helps
to ensure (an be obvious) that you are using the correct type. Also,
casting the results of malloc is recommended against in C to allow
errors to be reported (if, for example, a prototype for malloc has not
be seen).

> /*if bad allocation then return */
> if(!CompArray)
> {
> return;
> }

It's wise to check, but consider the affect on the function caller.
There is no indication to either the calling code or the user (via
stderr or stdout) that an error occurred or what it was.

> /*allocate the array and set the variables to Null */
> for(q = 0; q<= count ; h++)

q?
> {
> CompArray[q] = (struct Company ) malloc(sizeof(CompArray));

No. The space for the struct has already been allocated with the array.
You should eliminate this.

> CompArray[q]->employee= NULL;

^^ should be .

>
> /*Once the array is allocated then I pass it and the employee
> number to the other function */
> status = build_company_array(employe_number, CompArray);
> <----Should this be &ComArray instead?

No, unless the function will possibly reallocate the array and set the
new array address. If so, you would declare it differently and specify
a different functionality.

>
>
> In another module I would have the function build_company_array
>
>
> long build_company_array(int employee_number, structure CompArray)

This should be struct employee *CompArray ^^^^^^^^^^^^
> {
> /* Read the database and find a match on the employee number */
> int counter = 0;
> while (database_emp#)

You cannot use "#" as part of a variable name in C.

> {
>
> if (database_emp# == employee_number)
> {
> CompArray[count]employee = getName(employee_number);
> counter++;
> }
> }
> return 0;
> }
>
> I guess my questions pertain to proper allocation of the structure and
> the array. It's a simple straight forward structure so I don't think I
> need to make it a pointer to a structure do I?

That depends on what you want to do. You can declare a structure or an
array of structures without declaring a pointer. If you want to
dynamically allocate an array, you either need to declare a pointer or
use a C99 variable size array.

> 1) Am I defining my structure properly in my initial function? Should
> it be struct Company CompArray; or struct Company *CompArray;

Since you are dynamically allocating the array (which is not required
for the fixed size), you must declare a pointer to the struct.

> 2) Am I allocating the structure properly?

> 3) Am I allocating the array properly?

The structure array is allocated properly. The individual element
allocation is not.

> 4) Am I passing the array properly so that when it returns it will be
> populated with the right values that it built in the called function?

You are calling properly, but not declaring the function properly.

> can you guys help?

We try. ;=)

--