Single malloc for multiple data type

2.3k Views Asked by At

I am trying to write a code for which I need multiple arrays of different data types. These arrays need to be dynamically allocated. I need to consider the performance so I want to allocate all the arrays with one malloc call.

For simple case, lets say I need one integer and one double precision floating point array. So, I am doing the following.

int *iA;
double *dA;
void *vp;
vp = malloc( (sizeof(int)+sizeof(double))*N ); // assume N is known at this point.

// now to set the array pointers I am doing the following.
iA = vp;
dA = (void*)(iA+N); // This is wrong!!
...
free(vp);

If address in vp is multiple of 8 (which usually is) and N is an odd number, dA is set to an address that is not a multiple of 8. This causes all sorts of problem. It should be fine if I interchange iA and dA assignment. This seems a simple solution but if I have more than two arrays and more than two different types, it might not solve the issue. I am not sure.

So, my question is, what is the best way (in terms of performance) to allocate memory if you need multiple array of different data types?

NOTE: I am on a 64bit Linux machine, compiling code with gcc-4.9.0.

2

There are 2 best solutions below

3
On

what is the best way (in terms of performance) to allocate memory if you need multiple array of different data types?

  • In case you need very large amounts of memory, the overhead of calling malloc several times is most likely neglectable and trying to manually optimize the calls is then most likely just pre-mature optimization.

  • In case you don't need very large amounts of memory, use VLAs. These are typically allocated on the stack (compiler implements them by calling alloca or similar) so they are both way faster and way safer than dynamic allocation. For example:

    void local_function (size_t d_arr_n, 
                         size_t i_arr_n,
                         ...)
    {
      double double_arr [d_arr_n];
      int    int_arr    [i_arr_n];
      ...
    }
    
2
On

Problem

you have declared,

int *iA;

if you add a whole number, N to iA means, it will point to the Nth int location. i.e,

dA = iA + N; // then, dA = iA + N * sizeof(int)

Solution

If you want dA point to a location iA + N then declare iA as char * instead of int *.

char *iA; // will solve the problem

If you are planning to use mixed data type (e.g. int and double) use struct.

e.g.

struct MixedType
{
int a;
double b;
};

then use malloc to dynamically allocate memory,

MixedType *iA = (MixedType *)malloc(sizeof(MixedType));

if you want array of MixedType of N size; then,

MixedType *iA = (MixedType *)malloc(sizeof(MixedType) * N);

assign dA as in your code,

dA = (MixedType *)iA;

you can access a & b in MixedType like,

int a = dA->a;
double b = dA->b;