We help IT Professionals succeed at work.

arrays of structure

aagoh
aagoh asked
on
I have this...

typedef struct record {
int number;
int weight;
int height;
struct record *next;
} RECORD;

RECORD *file1;
int numRecord = 4;

file1 = ( RECORD * )malloc( 4 * sizeof( RECORD ) );

so that I can have array pointing to a structure.
but how to add new structure to the array,
and how to access the individual members of the array?

the normal linked list format doesn't work.
I thought this would work,
file1[i]->weight = 10;
file1[i]->next = NULL;

how to get the normal linked list format to work?

thanks
Comment
Watch Question

Author

Commented:
ok, I have figured out the first part.
I have declared wronly for the REORD *file1.
it should be
RECORD *file1;
ad the malloc would be
file1 = ( RECORD ** )malloc(4 * sizeof(RECORD *));

but the same questions remains.

:)
thanks in advance.

Author

Commented:
mistake
RECORD *file1
should be
RECORD **file1
If I understand your question well, then you want to implement a linked list with the structure definition you defined. Whenever a new node is added point the next to the new node and make the current node as the new node.

Programatically..

Assuming "current" is a global variable that is a pointer to the current starting node.
void
createNode(int no, int height, int weight)
{
    record* rec = (record*)malloc(sizeof(record));

    rec->number = no;
    rec->height = height;
    rec->weight = weight;
    current->next = rec;
    current = rec;
    current->next = NULL;
}

With this you need not declare a standard size for the linked list. You can grow it to as much as you want (with your maximum memory as a constraint).

Hope this helps!!!
Babu

Author

Commented:
err..
that's linked list alright.

actually I have not clearly stated the question.
what I want is an array of pointers pointing to structures.

I have figured out the first part.

typedef struct record {
int number;
int weight;
int height;
struct record *next;
} RECORD;

RECORD **file1;
int numRecord = 4;

file1 = ( RECORD ** )malloc( 4 * sizeof( RECORD * ) );

I can access the data like this,
for( i = 0; i < numRecord; i++ )
printf( "Record Number in file %d = %\n", file1[i]->number, file1[i]->number );

so, is the normal malloc-ing the same as per linked list?
file1[i] = file1 = ( RECORD * )malloc( 4 * sizeof( RECORD  ) );

and what about accessing the record?

thanks
CERTIFIED EXPERT
Commented:
with an array of structures you dont reall need a pointer to the next structure like you would in a linked list unless you want to use this pointer to order them in some way, in this case i would change it to an integer index.

so you have a stricture like this and want to have an array that you can incrase in size to accomodate new entries

typedef struct record {
int number;
int weight;
int height;
struct record *next; /* you do not need this field for an array */
} RECORD;

first write a function to add entries, so

RECORD* add_record(struct RECORD *array, int *count,RECORD *new_record)
{
   /* increase the callers count for them */
   *count = *count + 1;
   /* resize the array to accomate the new entry */
   array = (RECORD*)realloc(array,(*count * sizeof(RECORD)));
   /* copy the new_record in, remember *count -1 as arrays are 0 indexed */
   memcpy(array[*count - 1],new_record,sizeof(RECORD));
   /* return the array pointer because realloc may have moved the memory block, this would not be reflected in the array paramter as the pointer itself is passed by value */
   return array;
}

now in you caller,

make sure the first time you call this you pass NULL as the record array in the add function so realloc nows that the memory blockl for the array does not exist yet, subsequent calls should pass a pointer to the array of records.

RECORD *array = NULL;
int count = 0;
RECORD new_item;

/* init new item with values */

array = add_record(array,&count,&new_item);

/* another new item */
array = add_record(array,&count,&new_item);

for(int i=0;i<count;i++)
{
   printf("%d\n",array[i].number);
}

Paul

Author

Commented:
err..
that's linked list alright.

actually I have not clearly stated the question.
what I want is an array of pointers pointing to structures.

I have figured out the first part.

typedef struct record {
int number;
int weight;
int height;
struct record *next;
} RECORD;

RECORD **file1;
int numRecord = 4;

file1 = ( RECORD ** )malloc( 4 * sizeof( RECORD * ) );

I can access the data like this,
for( i = 0; i < numRecord; i++ )
printf( "Record Number in file %d = %\n", file1[i]->number, file1[i]->number );

so, is the normal malloc-ing the same as per linked list?
file1[i] = file1 = ( RECORD * )malloc( 4 * sizeof( RECORD  ) );

and what about accessing the record?

thanks
CERTIFIED EXPERT

Commented:
>>that's linked list alright.

no, a linked list is not an array at all, it is individual items allocated on the heap, each item having a pointer to the next item.

you need to completly restructure you code if you want a linked list.

also there is no need to use an array of pointers, you can just as weel use a straight array of structure, all you will acheive by using an ** is heap fragmentation!

Author

Commented:
err..
that's linked list alright.

actually I have not clearly stated the question.
what I want is an array of pointers pointing to structures.

I have figured out the first part.

typedef struct record {
int number;
int weight;
int height;
struct record *next;
} RECORD;

RECORD **file1;
int numRecord = 4;

file1 = ( RECORD ** )malloc( 4 * sizeof( RECORD * ) );

I can access the data like this,
for( i = 0; i < numRecord; i++ )
printf( "Record Number in file %d = %\n", file1[i]->number, file1[i]->number );

so, is the normal malloc-ing the same as per linked list?
file1[i] = file1 = ( RECORD * )malloc( 4 * sizeof( RECORD  ) );

and what about accessing the record?

thanks

Author

Commented:
opps..
sorry for the duplicated comments..
If you are talking of an array of structure nodes, then it is not a linked list. Its just an array. The definition of a linked list is not that.

Now if you really want to store elements in an array, then you can do it as,

Record rec[10];

Record* rec1 = (Record*)malloc(sizeof(Recorrd));

rec[0] = rec1;

And so on.

But a linked list is where you have a pointer to point to the next node of the list and you dont have an index to go to the particular node.

To traverse through the list, you need a Head pointer, to add a new record to the list, you need a Current pointer, and Next pointer just points to the next node in the list.

So you traverse through the list as.

Record* point = Head;

Record* Search(int no)
{
   while (point != NULL)
   {
      if (point->number == no)
      {
          printf("Got the node");
          return point;
      }
      else
      {
          point = point->Next;
      }
   }
}

The returned node holds the other fields of the record you wanted.

Commented:
I think I know what you want.  The first thing is to get rid of the "next" pointer from within your struct.  Then you can do the following:


RECORD    *pRecords = NULL;
RECORD    *pRecord;
int       NumRecords = 10;


{

    int   i;

    pRecords = malloc ( NumRecords * sizeof ( RECORD ) );
    pRecord  = pRecords;
    for ( i = 0; i < NumRecords; i++ )
    {
        pRecords [ i ]->number = i;
        pRecord->weight        = i;
        pRecord++;
        ...
    }

    ...



I have shown two possible methods for accessing data within the array of your structure.  The first method uses array subscript and sets the "number" element where as the pointer method sets the weight.  Typically if you need to remember the pointer as you would with pRecords then you should use the subscript method.  However when you pass pRecords to a function which is going to enumerate through the array and then return then the pointer method is perferable because it is much faster, not to mention cleaner to read.
I would like to add that x=realloc(x,newsize) can create a possible memory leak. What happens when the realloc fails (could happen)? then you have a NULL pointer, but have not freed the original memory. Something like below is probably better:

RECORD *file1;
RECORD *temporary;
int records=4;

file1=malloc(sizeof(RECORD)*records);

/* now lets change it's size */

temporary=realloc((records+1)*sizeof(RECORD));
if (temporary)
{
records++;
file1=temporary
}
else{
/* failed to rallocate, original data is still valid */
}

Commented:
Hi.

The best (my opinion) is to reallocate a space for your pointers, including the new one(s), and then copy your old array to the new, and then deallocating the old.

Another way is to prepare in advance a large array of pointers, and use only what you need.
(not too much consuming, but if you're tight in space...)

I don't think you can solve it otherwise..
Except for linked list..

  Erez Sh.

Commented:
   
to access the individual members of the array rty this:

record *file1;
int i, numRecord = 4;
struct record * data ;

file1 = ( record * )malloc( 4 * sizeof( record ) );
     
for (i=0; i<numRecord ; i++)
{
     data = file1 + i;
     data->height = 10;
     data->weight = 20;
     data->number = i + 1;
     data->next = NULL;
}

to add new structure to the array you should use
file1 = ( record * )realloc(file1, 8 * sizeof(record ) );
which will returns a pointer to the possibly moved block. (The contents are unchanged up to the lesser of the new and old sizes)

Commented:
u ahve to use calloc() function when u r going to use arrays!
CERTIFIED EXPERT

Commented:
>>u ahve to use calloc() function when u r going to use arrays!

thats not true; malloc will do it just does not initalise its items to 0
CERTIFIED EXPERT
Top Expert 2006

Commented:
No comment has been added lately and this question is therefore classified abandoned.

If asker wishes to close the question, then refer to
http://www.experts-exchange.com/help/closing.jsp

Otherwise, I will leave a recommendation in the Cleanup topic area that this question is:
PAQed with 30:70 split between sateesh_babu and makerp

Please leave any comments here within the next seven days. It is assumed that any participant not responding to this request is no longer interested in its final disposition.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Sunny
EE Cleanup Volunteer

Explore More ContentExplore courses, solutions, and other research materials related to this topic.