Home > Enterprise >  Malloc space for a pointer of array in C
Malloc space for a pointer of array in C

Time:11-13

I need to work upon a variable number of fixed-size arrays. More specifically, N points in a K-dimensional space, where I know K beforehand, but I don't know N at compile time. So I want to use a pointer to the fixed-size array, and allocate space for N K-dimensional points at runtime.

In C, I can allocate the said pointer with malloc. Example test.c below, where dimension is 3 for simplicity:

#include <stdlib.h>
#include <stdio.h>
#define DIMENSIONS  3

typedef float PointKDimensions[DIMENSIONS];

void do_stuff( int num_points){
  PointKDimensions *points;
  points = malloc(num_points * sizeof(PointKDimensions));
  points[5][0] = 0;    // set value to 6th point, first dimension
  points[5][1] = 1.0;  // to second dimension
  points[5][2] = 3.14; // to third dimension
  return;
}

int main(){
    do_stuff(10); // at run-time I find out I have 10 points to handle
    return 0;
}

I can compile this with gcc test.c without errors, and run without segmentation faults.

However, if I try to achieve the same behavior with C mv test.c test.cpp, followed by g test.cpp, I get:

test.cpp: In function ‘void do_stuff(int)’:
test.cpp:10:18: error: invalid conversion from ‘void*’ to ‘float (*)[3]’ [-fpermissive]
10 |   points = malloc(num_points * sizeof(float) * DIMENSIONS);
   |            ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   |                  |
   |                  void*

Searching up, I found that C does not do implicit conversions for malloc, so I changed the malloc to:

 points = (float*) malloc(num_points * sizeof(float) * DIMENSIONS);

And then the error becomes:

test.cpp: In function ‘void do_stuff(int)’:
test.cpp:10:12: error: cannot convert ‘float*’ to ‘float (*)[3]’ in assignment
   10 |   points = (float*) malloc(num_points * sizeof(float) * DIMENSIONS);
      |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |            |
      |            float*

But I could not find a way to do the appropriate cast/conversion to solve this error. E.g., (float**) is also not the same as float(*)[3].

Any suggestions on how to allocate space for a pointer to fixed-sized arrays in C ?

CodePudding user response:

You could use std:array for that.

e.g.

#include <array>

inline constexpr const size_t DIMENSIONS = 3;
using PointKDimensions = std::array<float, DIMENSIONS>;

CodePudding user response:

You need to cast the result of malloc as PointKDimensions* not as a float*:

typedef float PointKDimensions[DIMENSIONS];

void do_stuff( int num_points){
  PointKDimensions *points;
  points = (PointKDimensions*)malloc(num_points * sizeof(PointKDimensions));
  points[5][0] = 0;    // set value to 6th point, first dimension
  points[5][1] = 1.0;  // to second dimension
  points[5][2] = 3.14; // to third dimension
  return;
}

Or better, use C 's built-in container for dynamically sized arrays, std::vector:

vector<vector<float>> points;

void do_stuff( int num_points){
  points.resize(num_points, vector<float>(k)); // assuming k = number of dimensions.
  points[5][0] = 0;    // set value to 6th point, first dimension
  points[5][1] = 1.0;  // to second dimension
  points[5][2] = 3.14; // to third dimension
  return;
}
  • Related