help with array of structs 
Author Message
 help with array of structs

Hi,

I've modified some code I found on the net and I now need some help as I'm
getting to the borders of my knowledge of C.

I'd like to have an array of structures where one of the members of the
structure is dynamically allocated.  As an example I have an array of animal
structures and perhaps I want to store the weight of each animal
each day but I don't know how many days of data there will be until
runtime...

My annotated code is below...
Thanks in advance!  I've been tearing my hair out over this...

joe

===========================================================================
typedef struct {
  char    name[25];  /* okay since size is known when mallocing struct*/
  double  *weight;  /* can we allocate space for the array of structs without
                       knowing the size of the weight array? */
  int     age;

Quote:
} animal;

/* proto included here for convenience */
void InitAnimals(animal *pets[], int amax);
void InitAnimals(animal *pets[], int amax) {
  int index;
  for (index = 0;index < amax;index++) {
    pets[index] = (animal *)malloc(sizeof(animal));
    /* malloc success test removed for bretivy */
    strcpy(pets[index]->name,"SomePet");
    pets[index]->age = amax - index + 1;  /* arbitrary assignment */
  }

Quote:
}

void Animals(int amax) {
  int index;
  animal *pets[amax]; /* Is this allowed?
                         If not, is it possible do something similar? */
  animal *point;
  InitAnimals(pets, amax);
  /* deallocation removed for brevity */
  /* print out each pet's age (and weight?) */
  for (index = 0;index <amax;index++) {
    point = pets[index];
    printf("%s is %d years old.\n", point->name, point->age);
  }

Quote:
}

int main() {
  Animals(10);
  return 0;
Quote:
}

===========================================================================


Fri, 13 Aug 2004 19:23:30 GMT  
 help with array of structs

Quote:

> I'd like to have an array of structures where one of the
> members of the structure is dynamically allocated.

> typedef struct {
>   char    name[25];  
>   double  *weight;  
>   /* can we allocate space for the array of structs without
>      knowing the size of the weight array? */
>   int     age;
> } animal;

Initialize weight to NULL. Whenever you want to add another
weight, use realloc to resize the weight field. realloc is
guaranteed to copy the old values to the new memory space,
if it's necessary to move the old area.

You may also want to a (int) nweight field your struct to
keep track of the number of weights stored. Example:

  int add_weight(animal *ap, double nweight)
  {
  double *tmp;

    tmp = realloc(ap->weight, (ap->nweight+1) * sizeof(animal));
    if (tmp != NULL) {
      ap->weight = tmp;
      ap->weight[ap->nweight] = nweight;
      ap->nweight++;
    }
    return(tmp != NULL);
  }

That's all there is to it ...

willem



Fri, 13 Aug 2004 19:49:31 GMT  
 help with array of structs


Quote:
>Hi,

>I've modified some code I found on the net and I now need some help as I'm
>getting to the borders of my knowledge of C.

>I'd like to have an array of structures where one of the members of the
>structure is dynamically allocated.  As an example I have an array of animal
>structures and perhaps I want to store the weight of each animal
>each day but I don't know how many days of data there will be until
>runtime...

>My annotated code is below...
>Thanks in advance!  I've been tearing my hair out over this...

>joe

>===========================================================================
>typedef struct {
>  char        name[25];  /* okay since size is known when mallocing struct*/
>  double  *weight;  /* can we allocate space for the array of structs without
>                       knowing the size of the weight array? */

The terminology in your question is misleading.

        Your structure does not have a dynamically allocated member.  Each
element is completely defined at compile time with a fixed size and
offset from the start of the structure.

        One of the members is a pointer.  That pointer certainly can point
to a dynamically allocated area containing space for one or more
doubles.  On the other hand, it could just as easily point to any
other area of memory which contains one or more doubles.

The size of each weight array (there is one such array for each
instance of animal) has no relationship to the size of or the number
of structures.  Furthermore, there is no requirement that the arrays
pointed to by different instances of weight be the same size.

Quote:
>  int         age;
>} animal;

>/* proto included here for convenience */
>void InitAnimals(animal *pets[], int amax);
>void InitAnimals(animal *pets[], int amax) {

pets is not an array of structure.  It is an array of pointers to
structure but that is not the same thing.
Quote:
>  int index;
>  for (index = 0;index < amax;index++) {
>    pets[index] = (animal *)malloc(sizeof(animal));

Never cast the return from malloc to a pointer type.  It can never
help.  It can cause the compiler to suppress certain error messages
which can lead you to believe your code is correct when it is not.

You dynamically allocate space for a single structure for each element
(pointer) in the array.  This is excessive overhead (malloc is not a
cheap function) unless there is a chance that amax will be so large
that there is a risk that you could not allocate them all in one
contiguous block of memory.

If you really wanted an array of structure:

        Define it in the highest level function where it is needed and
pass it as an argument to the appropriate lower level functions.

        If you don't know the dimension until run time and your compiler
is not C99 compatible, define a scalar (not an array) pointer and use
a single call to malloc to allocate space for all the elements, such
as
                pointer = malloc(number_of_elements * sizeof *pointer);
You define and pass this pointer the same as describe above for a
defined array.

Quote:
>    /* malloc success test removed for bretivy */
>    strcpy(pets[index]->name,"SomePet");
>    pets[index]->age = amax - index + 1;  /* arbitrary assignment */
>  }
>}

>void Animals(int amax) {
>  int index;
>  animal *pets[amax]; /* Is this allowed?
>                     If not, is it possible do something similar? */

Didn't your compiler generate an error message for this.  Mine did.
Solutions described above.

Quote:
>  animal *point;
>  InitAnimals(pets, amax);
>  /* deallocation removed for brevity */
>  /* print out each pet's age (and weight?) */
>  for (index = 0;index <amax;index++) {
>    point = pets[index];
>    printf("%s is %d years old.\n", point->name, point->age);
>  }
>}

>int main() {
>  Animals(10);
>  return 0;
>}
>===========================================================================

<<Remove the del for email>>


Sat, 14 Aug 2004 16:10:17 GMT  
 help with array of structs
Thanks!  I had tried something similar but was confused because an
array was getting referenced out of bounds in another part of the code
and was segfaulting during the malloc for the array of doubles.
It wasn't even a routine I had written that was causing the problem,
honest ;)  Completely unrelated pieces of code.  Gotta love
hard-to-track-down memory problems.  Is there a way to track such
things using a C compiler flag??  Obviously it might have been a
good idea to try purify first...

Thanks again!

joe

Quote:

> Initialize weight to NULL. Whenever you want to add another
> weight, use realloc to resize the weight field. realloc is
> guaranteed to copy the old values to the new memory space,
> if it's necessary to move the old area.

> You may also want to a (int) nweight field your struct to
> keep track of the number of weights stored. Example:

>   int add_weight(animal *ap, double nweight)
>   {
>   double *tmp;

>     tmp = realloc(ap->weight, (ap->nweight+1) * sizeof(animal));
>     if (tmp != NULL) {
>       ap->weight = tmp;
>       ap->weight[ap->nweight] = nweight;
>       ap->nweight++;
>     }
>  return(tmp != NULL);
>   }

> That's all there is to it ...

> willem



Sat, 14 Aug 2004 17:29:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Help with array of struct in func

2. help with array withen struct

3. Aarghh! I need help with array of structs

4. Problem with struct/array inside a struct using fread/fwrite

5. struct.array works - struct->pointer not

6. Initialisation of structs containing arrays of structs...?

7. native dll calling with structs containing arrays of nested structs

8. Help: Pointer to 2-D array of structs.

9. Help with an Array of struct

10. help me sort my array of structs

11. Pointer to a struct within an array Help Please

12. Help wanted with array of pointers to structs

 

 
Powered by phpBB® Forum Software