0

I'm pretty new to C syntax, but here's my problem:

I want to create a pointer which stores multiple float arrays.

From what I know, here's the approach (?):

  • I have to create some sort of pointer to access these arrays from other functions.
  • Dynamically allocate it some memory (for the arrays) with malloc.
  • I have to point it to each of the float arrays I am creating.
int size = 100;

float *template[66]; //for 66 float arrays
malloc...
memset(&(template[i]), 0, size*sizeof(float));

Need some guidance on the code sequence to make this work!

alk
  • 69,737
  • 10
  • 105
  • 255
Gabriel
  • 438
  • 1
  • 5
  • 16
  • So you want 66 float arrays each having a size of 100? – Jabberwocky Dec 16 '19 at 06:55
  • 2
    Pointers store the addresses of other objects, they don't store arrays. You can have arrays , and you can have -- elsewhere in memory -- variables which hold the address of those arrays . Or the address of the first element of those arrays. Keeping these concepts clear in your mind will help with finding the right syntax to use . – M.M Dec 16 '19 at 06:55
  • my apologies, it should be `float* template[66]`; – Gabriel Dec 16 '19 at 06:55
  • 1
    Also please try to create a [mcve] of your own attempt, and describe your problems with it. And please take some time to refresh [how to ask good questions](http://stackoverflow.com/help/how-to-ask), as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Dec 16 '19 at 06:55
  • 1
    Do you want the 66 arrays of floats to already exist or want to only create them when the situation arises? – Yunnosch Dec 16 '19 at 06:58
  • [THIS](https://stackoverflow.com/a/7307699/3436922) should help – LPs Dec 16 '19 at 07:00
  • the 66 arrays should already exist, and i should be able to call them from the pointer any other time! – Gabriel Dec 16 '19 at 07:00
  • By the way, if `template[i]` (for any valid index `i`) is a pointer, then `&template[i]` is a pointer *to the pointer* and will have the type `float **`. That's not really what you want. – Some programmer dude Dec 16 '19 at 07:02
  • 1
    Why not `float (*template)[100] = calloc(66, sizeof *template);` - done. – WhozCraig Dec 16 '19 at 07:08
  • Do the arrays all have the same size or may they have individual length ("jagged array")? The correct solution is different between these two cases. – Lundin Dec 16 '19 at 10:09

4 Answers4

1

You can take the address of an object at any time, you do not need to have pointer variables to also hold their address.

For your requirements as stated so far you can allocate one block of memory for all the arrays:

float (*p)[100] = malloc( sizeof(*p) * 66 );

which gives you 66 blocks of 100 floats . Then you can initialize with a loop:

for (int i = 0; i < 66; ++i)
    for (int j = 0; j < 100; ++j)
         p[i][j] = 0.f;

If a function needs the third array you can give it p[2] (or &p[2]), you do not need some variable to store p[2] because you can get it at any time by writing p[2] . You only need to store p .

M.M
  • 138,810
  • 21
  • 208
  • 365
1

If all sizes are known (at compile time), then those array can be created by just defining them.

either separately:

float f00[100] =  {0., /* 98 more floats */ 99.};
  /* 64 more arrays */
float f65[100] =  {0., /* 98 more floats */ 99.};

float * arrays[66] = {
  f00,
  /* 64 more arrays */
  f65,
}

or all in one go:

float * arrays[66] = {
  (float[100]){0., /* 98 more floats */ 99.},
  /* 64 more arrays */
  (float[100]){0., /* 98 more floats */ 99.},
}

or all in one go using a 2D-array, and from this deriving the single array pointers:

float array2d[66][100];

float * f00 = array2d[0];
/* 64 more float pointer here */
float * f65 = array2d[65];

or the latter dynamically:

float (*array2d)[66][100] = malloc(sizeof *array2d); 

float * f00 = array2d[0];
/* 64 more float pointer here */
float * f65 = array2d[65];

/* use it here */

free(array2d);
alk
  • 69,737
  • 10
  • 105
  • 255
0

The code will be like this:

int size = 100;
int number_of_arrays = 66;

float *template[number_of_arrays ]; //for 66 float arrays
for(int i = 0; i< number_of_arrays; ++i){
    template[i] = (float*)malloc(size * sizeof(float)); 
    memset((template[i]), 0, size*sizeof(float));
}

you have to allocate with malloc every single array, and assign the returned pointer to the i-th element of the "array of array"

The memset doesn't need the "&"(reference) of the "template[i]" because "template[i]" is already a pointer.

Zig Razor
  • 3,381
  • 2
  • 15
  • 35
0
int i;
/* this should really be const! */
const int number_of_arrays = 66;
const int size = 100;

/* 
 * I would recommend NOT using 'template' as a variable name.
 * It's a reserved keyword in C++, so probably a good idea to avoid it!
 */

float* myTemplate[number_of_arrays];

for(i = 0; i < number_of_arrays; ++i)
{
  /* allocate 100 floats */
  myTemplate[i] = (float*)malloc(size * sizeof(float));

  /* set all float values to zero */
  memset(myTemplate[i], 0, size * sizeof(float));
}
robthebloke
  • 9,331
  • 9
  • 12
  • 1
    This only makes sense if the individual arrays should be allowed to have different sizes. Otherwise it is needlessly inefficient. – Lundin Dec 16 '19 at 10:11