C++ 中的数组指针的 Malloc space

Malloc space for a pointer of array in C++

我需要处理可变数量的固定大小数组。更具体地说,N 指向 K 维 space,其中我事先知道 K,但在编译时不知道 N。 所以我想用一个指向固定大小数组的指针,在运行时分配space给N个K维点。

在C中,我可以用malloc分配上述指针。下面的示例 test.c,为简单起见,维度为 3:

#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;
}

我可以用 gcc test.c 编译它而没有错误,并且 运行 没有分段错误。

但是,如果我尝试使用 C++ mv test.c test.cpp 实现相同的行为,然后使用 g++ test.cpp,我会得到:

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*

查了一下,发现C++没有对malloc做隐式转换,所以把malloc改成:

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

然后错误变为:

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*

但我找不到合适的方法 cast/conversion 来解决这个错误。例如,(float**) 也不同于 float(*)[3]

关于如何在 C++ 中为指向固定大小数组的指针分配 space 有什么建议吗?

你可以使用 std:array

例如

#include <array>

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

您需要将 malloc 的结果转换为 PointKDimensions* 而不是 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;
}

或者更好的是,对动态大小的数组使用 C++ 的内置容器,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;
}