Array of Structures

S

Sam

Hello I have a structure called Company.

struct Company
{
char *employee;
char *employee_address;
};

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;
CompArray[q]->employee_address= 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);
<----Should this be &ComArray instead?


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);
CompArray[count]employee_address =
getAddress(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
 
L

liorm

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
 
P

pete

Sam said:
Hello I have a structure called Company.

struct Company
{
char *employee;
char *employee_address;
};
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;
char *employee_address;
};

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;
CompArray[index].employee_address = NULL;
}
random = rand() % COUNT;
CompArray[random].employee = malloc(sizeof "Fred");
if (CompArray[random].employee == NULL) {
puts("CompArray[random].employee == NULL");
exit(EXIT_FAILURE);
}
CompArray[random].employee_address
= malloc(sizeof "11 Maiden Lane");
if (CompArray[random].employee_address == NULL) {
puts("CompArray[random].employee_address == NULL");
exit(EXIT_FAILURE);
}
strcpy(CompArray[random].employee, "Fred");
strcpy(CompArray[random].employee_address, "11 Maiden Lane");
puts("/* BEGIN new.c output */\n");
puts(CompArray[random].employee);
puts(CompArray[random].employee_address);
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[index].employee_address);
}
free(CompArray);
}

/* END new.c */
 
K

Keith Thompson

liorm said:
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.

Pleaes provide context. Read <http://cfaj.freeshell.org/google/> to
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/>.
 
C

CBFalconer

Sam said:
Hello I have a structure called Company.

struct Company
{
char *employee;
char *employee_address;
};

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:

<http://cbfalconer.home.att.net/download/hashlib.zip>

--
"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
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
S

Sam

Hello everybody base upon the information that I got from you guys I
made the following changes

struct EmpInfo
{
char *employee;
char *employee_address;
};

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;
EmpArray[q]->employee_address= 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(EmpArray[q]->employee_address);
}
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(EmpArray[q]->employee_address);
}
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);
EmpArray[count]employee_address = (char
*)malloc(sizeof(getAddress

(employee_number)));
EmpArray[count]employee_address =
getAddress(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(EmpArray[q]->employee_address);
}
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




Sam said:
Hello I have a structure called Company.

struct Company
{
char *employee;
char *employee_address;
};
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;
char *employee_address;
};

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;
CompArray[index].employee_address = NULL;
}
random = rand() % COUNT;
CompArray[random].employee = malloc(sizeof "Fred");
if (CompArray[random].employee == NULL) {
puts("CompArray[random].employee == NULL");
exit(EXIT_FAILURE);
}
CompArray[random].employee_address
= malloc(sizeof "11 Maiden Lane");
if (CompArray[random].employee_address == NULL) {
puts("CompArray[random].employee_address == NULL");
exit(EXIT_FAILURE);
}
strcpy(CompArray[random].employee, "Fred");
strcpy(CompArray[random].employee_address, "11 Maiden Lane");
puts("/* BEGIN new.c output */\n");
puts(CompArray[random].employee);
puts(CompArray[random].employee_address);
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[index].employee_address);
}
free(CompArray);
}

/* END new.c */
 
S

Sam

Hello everybody base upon the information that I got from you guys I
made the following changes

struct EmpInfo
{
char *employee;
char *employee_address;
};

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;
EmpArray[q]->employee_address= 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(EmpArray[q]->employee_address);
}
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(EmpArray[q]->employee_address);
}
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);
EmpArray[count]employee_address = (char
*)malloc(sizeof(getAddress

(employee_number)));
EmpArray[count]employee_address =
getAddress(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(EmpArray[q]->employee_address);
}
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
Sam said:
Hello I have a structure called Company.

struct Company
{
char *employee;
char *employee_address;
};
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;
char *employee_address;
};

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;
CompArray[index].employee_address = NULL;
}
random = rand() % COUNT;
CompArray[random].employee = malloc(sizeof "Fred");
if (CompArray[random].employee == NULL) {
puts("CompArray[random].employee == NULL");
exit(EXIT_FAILURE);
}
CompArray[random].employee_address
= malloc(sizeof "11 Maiden Lane");
if (CompArray[random].employee_address == NULL) {
puts("CompArray[random].employee_address == NULL");
exit(EXIT_FAILURE);
}
strcpy(CompArray[random].employee, "Fred");
strcpy(CompArray[random].employee_address, "11 Maiden Lane");
puts("/* BEGIN new.c output */\n");
puts(CompArray[random].employee);
puts(CompArray[random].employee_address);
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[index].employee_address);
}
free(CompArray);
}

/* END new.c */
 
T

Thad Smith

Sam said:
Hello I have a structure called Company.

struct Company
{
char *employee;
char *employee_address;
};

As Charles Falconer suggests, your structure name is misleading. Consider

struct employee
{
char *name;
char *address;
};

The point is that your nomenclature should not be misleading to the code
reader.
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
linking elements)
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);
CompArray[count]employee_address =
getAddress(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. ;=)
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top