【问题标题】:Create 2D array using size from parameters in C++使用 C++ 中参数的大小创建二维数组
【发布时间】:2017-04-21 22:17:48
【问题描述】:

我正在尝试创建一个简单的二维数组,其大小是方法传递的参数。在 C# 中我们会有这样的东西:

float[,] GenerateNoiseMap(int mapWidth, int mapHeight){
     float noiseMap[,] = new float[mapWidth, mapHeight];
     return noiseMap;
}

知道如何创建一个二维数组并在 C++ 中返回它吗? 到目前为止,编译器给我一个错误,即大小必须是一个常量值,我希望这些值是方法参数的值

【问题讨论】:

标签: c++ arrays


【解决方案1】:

我喜欢一维向量的简单包装器:

#include <vector>

class Matrix
{
private:
    size_t rows, columns;
    std::vector<double> matrix;
public:
    Matrix(size_t numrows, size_t numcols) :
            rows(numrows), columns(numcols), matrix(rows * columns)
    {
    }

    double & operator()(size_t row, size_t column)
    {
        return matrix[row * columns + column]; // note 2D coordinates are flattened to 1D
    }

    double operator()(size_t row, size_t column) const
    {
        return matrix[row * columns + column];
    }

    size_t getRows() const
    {
        return rows;
    }
    size_t getColumns() const
    {
        return columns;
    }
};

Documentation for std::vector

用法:

Matrix noiseMap(mapWidth, mapHeight);

【讨论】:

  • 会像:float** noiseMap = new float*[mapWidth]; for (int i = 0; i
  • @NathanielCutajar 每次调用new 时,都会获得另一块内存。分配存储可能非常耗时,因此您做的越少越好。接下来,您无法控制此内存块的存储位置。这破坏了空间局部性和访问的可预测性。如果 2D 数组中的行很短,则等待 CPU 查找和加载下一行的时间可能比处理时多几个数量级。单个内存块问题不大。
  • 但我真正喜欢的是它几乎是零维护。想把它搞砸几乎是不可能的。当您销毁Matrix 时,它会占用其所有存储空间,从而使内存泄漏变得更加困难。对于数组数组,您首先必须delete 所有行,然后您必须delete noiseMapMatrix 你可以放开范围,它就消失了。所有的。干净整洁。
  • 它也被紧紧包裹着,因此很难意外或故意损坏。您可以轻松添加防御措施,例如检查越界访问,因为您只需要在两个函数中进行编辑。使用数组数组,有人可能会delete noiseMap[4]; 或不小心将一行设置为 NULL,而您总是不得不传递它的大小。有很多额外的错误空间。
  • 我很快就会对此表示赞同。最后一个问题。如果我要访问一个变量,比如(在 C# 中)int myChoice = noiseMap[1,4],那么 Matrix 将如何工作?
【解决方案2】:

在 C++ 中,您不能在两个维度上都具有动态大小的二维 C 类数组。 C# 数组看起来有点像,但它们根本不是一回事。

为此我推荐boost::multi_array

#include <boost/multi_array.hpp>

boost::multi_array<float, 2> GenerateNoiseMap(int mapWidth, int mapHeight) {
    return boost::multi_array<float, 2>{boost::extents[mapWidth][mapHeight]};
}

【讨论】:

  • 请注意我正在使用虚幻引擎来创建这个项目,所以理想情况下应该有一个已经内置的类
  • @NathanielCutajar 我对 UE 不熟悉,但奇怪的是,我自己的搜索没有找到任何东西。
【解决方案3】:
float ** create_matrix(size_t m, size_t n)
{
    float ** answer = new float*[m];
    for (size_t i =0; i < m; i++)
        answer[i] = new float[n];
    return answer;
}

【讨论】:

  • 这实际上不是一个二维数组,而是一个(指向)数组的数组。它有很多缺点,例如内存不连续,您需要确保每个数组都被再次释放。
猜你喜欢
  • 2023-01-25
  • 1970-01-01
  • 2015-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-07
相关资源
最近更新 更多