Search code examples
cwindowsmallocrealloc

What is the correct way to dynamcially allocate memory for a struct?


I'm working on a program, which should search the registry for specific values, and store them, and their path in an array. So i don't know how many keys the program will find, and therefore i need to use a dynamically growing array. I use this code right now, but i'm not sure if it is correct.

struct data
{
char * Path;
char * Key;
};
struct data **RegArray = NULL;

int ArrayCount = 0;

// ....
// ....

// search the registry here....

// value has been found, so i should add it to the array here
RegArray = ( struct data **)realloc( RegArray, ( ArrayCount + 1 ) * sizeof( struct data *) );
RegArray[ ArrayCount ] = ( struct data *)malloc( sizeof( struct data ) );

RegArray[ ArrayCount ]->Path = _strdup( CurrentPath );
RegArray[ ArrayCount ]->Key = _strdup( CurrentKey );

ArrayCount++;

Could someone tell me please if this could is ok, or not. If not, how should i do it correctly?

Thanks!


Solution

  • You have got the gist of it. However, there are a few improvements you should make:

    1. Don't cast the return value of malloc, realloc, calloc, etc.:

      RegArray[ ArrayCount ] = ( struct data *)malloc( sizeof( struct data ) );
      

      ...becomes...

      RegArray[ ArrayCount ] = malloc( sizeof( struct data ) );
      
    2. To prevent memory leaks, always realloc to a temporary variable before assigning to the intended location after checking if it was successful:

      RegArray = ( struct data **)realloc( RegArray, ( ArrayCount + 1 ) * sizeof( struct data *) );
      

      ...becomes...

      struct data **tmp = realloc( RegArray, ( ArrayCount + 1 ) * sizeof( struct data *) );
      if (tmp == NULL) {
          /* handle error case */
      }
      RegArray = tmp;
      
    3. Always check the return value of malloc, realloc, calloc, etc.:

      RegArray[ ArrayCount ] = ( struct data *)malloc( sizeof( struct data ) );
      

      ...becomes...

      RegArray[ ArrayCount ] = malloc( sizeof( struct data ) );
      if (RegArray[ ArrayCount ] == NULL) {
          /* handle error case */
      }
      
    4. Use the variable rather than the type when using sizeof. I also usually drop the useless parenthesis around the expression in sizeof to improve readability:

      RegArray[ ArrayCount ] = malloc( sizeof( struct data ) );
      

      ...becomes...

      RegArray[ ArrayCount ] = malloc( sizeof **RegArray );