Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

dynamic allocation of array of structures

Status
Not open for further replies.

gorgor

Programmer
Aug 15, 2002
164
US
I have a structure in a C program defined:

struct {
char *Name;
char *Mod_Image;
char *ICA_Image;
int IsActive;
int ICAControl_ID;
int Panel_Handle;
int Panel_IsOpen;
ViReal64 Size;
} Module[100];

Instead of statically allocating an array of 100 of these structures like I have done, I want to dynamically allocate the array at run-time. I've done dynamic allocation of char arrays and int arrays, but never an array of structures containing chars and ints. Can someone give me some hints? Thanks in advance!
 
typedef struct module {
// you stuff
} MODULE;

MODULE * modulePtr = NULL;
int nModuleElms = 0;

and further, to _increase_ to one more element:

MODULE * tmpPtr = realloc(modulePtr,nModuleElms+1);
if (tmpPtr == NULL)
{
// no more memory
}
else
{
modulePtr = tmpPtr;
nModuleElms++;
}
 
hi,
there is not diff between allocating space for anything:

you must however perform a malloc( NUM x sizeofelem ).

Remember that if you know from begin of program the
value of NUM, is no useful to use malloc, but you make
only problem to you.

However use:

/////////////////////////////////// Declarations
struct ICA_Data_tag
{
char Name[20];
int IsActive;
...
};

/////////////////////////////////////// Allocate area
struct ICA_Data_tag* pBase, pUse ;
int size = num * sizeof( struct ICA_Data_tag )
pBase = (struct ICA_Data_tag*) malloc( size ) ;

pUse = pBase ;

/////////////////////////////////////// Loading
strcpy( pUse->Name, "One" ) ;
pUse->IsActive = FALSE ;
pUse++ ;

strcpy( pUse->Name, "Two" ) ;
pUse->IsActive = FALSE ;
pUse++ ;
......
strcpy( pUse->Name, "END" ) ; // you can use as EOF

....

///////////////////////////////////// Loop inside struct
for( pUse=pBase ; strcmp(pUse->Name,"END") ; pUse++ )
{
if( pUse->IsActive )
printf( "%s\n", pUse->Name);
...
}



You cannot extend "size" dynamically while other
connections take place. I suggest to use fixed array
of struct and take in mind ( by a counter ) the maximum
index used.

The use of malloc take sense when you have to create more
than one temporary area that you create-use-destroy:
if you create it at begin of program malloc(10000) use
it and destroy at the end (remeber to do it), it has no sense: declare char big[10000] and all is easier.

Note: I hope you don't want use the field "char *Name"
and the other char*, to store the name, modimg, icaimg
in your application: by this notation you store a pointer
to a area that contains data, not a dynamic string as in
VBasic or C++ (using str$ and CString class).
If you want store names, you must use char Name[20],
char mod_image[256], char ica_image[256].


BYE
 
Here is a trivial example that works okay with gcc and linux.
No real error checking and there could be a leak somewhere, but that's the trouble with dynamic allocation.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


struct ModuleT1 {
char    *Name;
char    *Mod_Image;
char    *ICA_Image;
int     *attr;
};

struct ModuleT1 **makeModArray(int);
void FreeModArray(struct ModuleT1 **, int);
void printMods(struct ModuleT1 **,int);

int main(void) {
int y = 0, d;
struct ModuleT1 **modarray =  NULL;


    while (y++ < 12)  {
           printf(&quot;Number of elements: &quot;);
           scanf(&quot;%d&quot;, &d);
           if ( (modarray = makeModArray(d)) == NULL) {
                printf(&quot;Malloc() failed\n&quot;);
                exit(1);
            }
          
            printMods(modarray,d);
            FreeModArray(modarray,d);
     }
return 0;
}
          

struct ModuleT1 **makeModArray(int sz) {
int y;
int attr[4] = {0,0,0,0};
struct ModuleT1 **new = malloc(sz * sizeof(struct ModuleT1 *));

      if (!new) {
          return NULL;
      }
     for (y=0 ; y < sz ; y++) { 
      new[y] = malloc(sizeof(struct ModuleT1));
      new[y]->Name = malloc(100 * sizeof(char));
      new[y]->Mod_Image = malloc(100 * sizeof(char));
      new[y]->ICA_Image = malloc(100 * sizeof(char));
      new[y]->attr = malloc(4 * sizeof(int)); 
      memcpy(new[y]->attr,attr,sizeof(attr)); 
      }

return new;
}
          
void printMods(struct ModuleT1 **arr,int sz) {
int p = 0,m;
       while (p < sz) {
          printf(&quot;Name at %p, Mod_image at %p, ICA_image at %p\n&quot;,arr[p]->Name,arr[p]->Mod_Image,arr[p]->ICA_Image);
          for (m=0 ; m < 4 ; m++) {
              printf(&quot;Value at index %d = %d\n&quot;, m, arr[p]->attr[m]);
          }
           p++;
       }
}

void FreeModArray(struct ModuleT1 **arr, int sz) {
int p,n = 0;

    while (p < sz) {
       free(arr[p]->Name);
       free(arr[p]->Mod_Image);
       free(arr[p]->ICA_Image);
       free(arr[p]->attr);
       free(arr[p]);
       p++;
    }

free(arr);
}
 
Drat, forgot something,

In my post, change the realloc line to:

MODULE * tmpPtr =
realloc(modulePtr,sizeof(MODULE *)*(nModuleElms+1));

Contents are copied (including the &quot;pointers&quot;), but you have to initialise the &quot;new&quot; space yourself.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top