Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Can we use single malloc() block to represent two different types?

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 ?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading