Home > Software design >  C calloc and vla
C calloc and vla

Time:09-22

I have a huge code but to for testing I created following sample code

#include <stdio.h>
#include <stdlib.h>

#define POSSIBLE_HEIGHTS 10
#define POSSIBLE_LENGTHS 10

typedef struct amap {
  int *va_height;
  int *va_length;
} amap_t;

static amap_t *mymap[10];

int prepare_mymap(amap_t **);

int main (int argc, char *argv[]) {

  prepare_mymap(&mymap[0]);

  short int cnt;
  int max = 10;
  for (cnt = 0; cnt < max;   cnt){
    if (mymap[cnt] != NULL){
      if (mymap[cnt]->va_height == NULL){
        printf ("Heights are not set for : %d\n", cnt);
      }
    }
  }
  return 0;
}


int prepare_mymap (amap_t **arg_map){
  short int i;
  for (i =0; i < 10;   i){

    if (i % 2 == 0) {
      int r = posix_memalign ((void **) &arg_map[i], 16,
                  (sizeof(int) * POSSIBLE_HEIGHTS));
                  
      if (r != 0) {
        printf ("memalign failed @ %d\n", i);
      } else {
        printf ("mem allocated @ %d\n", i);
      }
    } 
  }
  return 0;
}

I want to make *mymap[10] dynamic. Function prepare_mymapp() will determine the number of elements in mymap; Out of which some are allocated and some are not. My question is without changing access methods in main is it possible to make static amap_t *mymap[10]; dynamic?

I do not want change main() since its a huge code that uses pointer and checking against NULL.

    if (mymap[cnt] != NULL){
      if (mymap[cnt]->va_height == NULL){
        printf ("Heights are not set for : %d\n", cnt);
      }
    }

If I do following:

static amap_t *mymap;
prepare_mymap(&mymap);

and

int prepare_mymap (amap_t **arg_map){
  int arg_map_size = 10;
  *arg_map = malloc (sizeof(amap_t *) * arg_map_size);
  ....
  posix_memalign.....

} 

then my main changes to this.

    if (*mymap[cnt] != NULL){
      if (mymap[cnt].va_height == NULL){
        printf ("Heights are not set for : %d\n", cnt);
      }
    }

Is there a way to avoid it? Will *** help me?

CodePudding user response:

One approach to make static amap_t* mymap[10] a dynamic array is to declare it this way:

static amap_t** mymap;

Accordingly, your prepare_mymap() function becomes:

static amap_t** mymap;

int prepare_mymap(amap_t*** arg_map) {
  size_t arg_map_size = 10;
  *arg_map = malloc(arg_map_size * sizeof(amap_t*));
  ...
}

int main(void) {
  prepare_mymap(&mymap);
  ...
}

Alternatively, your prepare_mymap() function may return directly the pointer (so you don't need a "three star" pointer as argument):

static amap_t** mymap;

amap_t** prepare_mymap(void) {
  size_t arg_map_size = 10;
  amap_t** result = malloc(arg_map_size * sizeof(amap_t*));
  ...
  return result;
}

int main(void) {
  mymap = prepare_mymap();
  ...
}

If you want, you can replace malloc() in my previous examples with posix_memalign(). For instance:

// this line of code
*arg_map = malloc(arg_map_size * sizeof(amap_t*));
// becomes
void* temp;
int r = posix_memalign(&temp, alignment, arg_map_size * sizeof(amap_t*));
*arg_map = temp;
  • Related