I am writing a function where I need to call malloc multiple times to allocate memory for very small arrays dynamically (like 4-5 ints). These arrays are used to store different types of datatypes. so I thought of allocating a large memory and use it for all types. Here is what I am trying to.
#include <stdio.h>
#include <stdlib.h>
int main() {
char * a = malloc( 4*sizeof(char) + 4*sizeof(float) ); /* Allocating for 4 ints and 4 chars*/
for (int i=0; i<4 ; ++i) a[i] = 'a' ;
float *b = (void *)(a+4) ; /* can we cast this pointer in this way ?*/
for (int i=0; i<4 ; ++i) b[i] = 1.0f ;
for (int i=0; i<4 ; ++i) printf("%c" , a[i]) ;
printf("\n");
for (int i=0; i<4 ; ++i) printf("%f " , (double)b[i]) ;
printf("\n");
return 0;
}
I am now confused, is this a good allowed practice ?
>Solution :
This is not necessarily a good practice, because you’d need to not only care about the size of b but its alignment requirements. Suppose you only needed 2 chars and you used this code, then your float would be improperly aligned on all currently common platforms.
If you know the sizes during the compilation time, just allocate a structure:
struct foo {
char c[4];
float f[4];
}
and the compiler will take care of the rest. Otherwise, if dynamic, and your char array was say 6 elements, you need to round that 6 up to the nearest multiple of alignof(float) (most likely 8). Of course you need to allocate sufficient amount of memory too, i.e. just not the sum of the array elements but account for the padding as well, i.e. suppose you allocate 6 chars, 6 floats, you’d probably end up with 6 chars, 2 padding bytes, 6 * 4 bytes for floats.
The cast itself is thought to be legal, and so is the pointer arithmetic, since all this is pointing to an allocated array with no effective type.
Another way to not bother with alignof is to put the float array first – alignof(char) will be 1, and therefore you can always pack them as tightly as possible.