【问题标题】:Why C++ does not have a convenient way to dynamically allocate memory for multidimensional array? [closed]为什么 C++ 没有方便的方法为多维数组动态分配内存? [关闭]
【发布时间】:2017-02-16 23:50:12
【问题描述】:

在 C++ 中,我觉得很不方便,因为 C++ 没有内置的特性来在运行时为多维数组动态分配内存。

在 Java 中,我们只需一行代码即可。例如,在 Java 中,我们可以使用

为 4D 整数数组动态分配内存
int a, b, c, d;
std::cin>>a>>b>>c>>d;
int[ ][ ][ ][ ] array = new int[a][b][c][d];

我用谷歌搜索了在 C++ 中做同样事情的解决方案。但我发现,在 C++ 中,我们必须使用嵌套循环、容器或一些具有函数的结构来实现相同的功能。既然这样的语法特性会很方便,我想问一下为什么C++没有加入这样的内置特性?

【问题讨论】:

  • 有趣的事实:Java 中的 4D 数组?它不是 4D 数组。它是整数数组数组的数组。它可能会非常缓慢,因为每个动态分配的子数组之间没有连接。 CPU 从一个分配跳到下一个分配,并且永远无法从预加载到缓存中的连续数据中获得速度。可怕的嵌套循环 C++ 解决方案做同样的事情,而且很可怕。除非您需要锯齿状数组,否则不要使用任何一种语言。围绕一维数组创建一个包装器,为您处理索引。

标签: c++ arrays multidimensional-array


【解决方案1】:

在 C++ 中,您也可以通过这种方式分配内存。例如:)

auto array = new int[3][4][5][6];

还是一样

int ( *array )[4][5][6] = new int[3][4][5][6];

或者你可以使用 typedef 之类的

typedef int T[4][5][6];
// or
// using T = int[4][5][6];

T *array = new T[3];

问题是除了最左边的方块中的表达式必须是常量表达式。

【讨论】:

  • 另一个问题是它有内存泄漏的倾向,例如当你以不寻常的方式退出时
  • 谢谢!我忘了我们可以使用自动。所以这里的 auto 类型会和 int * array[ ][ ][ ] 一样吗?你的回答真的很有帮助!但是有没有办法通过在运行时使用非常量表达式来做到这一点?大多数时候,我不需要使用多维数组。但我决定好好学习 C++,并想知道更多关于它的细节。因此,我的第二个问题是什么上下文适合使用多维数组?我们总是需要避免它们吗?
  • @HanM 查看我更新的帖子。我展示了替代声明。不幸的是,表达式必须是常量。因此,当在编译时不知道元素的数量时,通常使用标准容器来代替数组,例如 C++ 中的 std::vector。
【解决方案2】:

首先,永远不要使用new。一切都有更好的选择。

步骤零,正确包含

#include <gsl/multi_span>
#include <memory>

第一步,设置尺寸

constexpr int x_sz = 3;
constexpr int y_sz = 4;
constexpr int z_sz = 5;
constexpr int total = x_sz * y_sz * z_sz;

第二步,分配内存

auto arrptr = std::make_unique<int[]>( total );

第三步,创建数组视图

gsl::multi_span<int, x_sz, y_sz, z_sz> arr3d { arrptr.get(), total };

恭喜,你有一个经过边界检查的三维数组 当它超出范围时,它将自行释放。

你可以找到GSLhere

【讨论】:

  • 谢谢! GSL还没有完成吗?我打算在它完成后阅读。
【解决方案3】:

我们也可以创建一个大小为 (M,N) 的二维矩形数组

auto array = (int (*)[N]) new int [ M*N ];

和一个大小为 (L,M,N) 的 3D 数组

auto array = (int (*)[M][N]) new int [ L*M*N ];

等(其中 L、M、N、... 可以是变量)。为此定义宏可能很方便。另外,如果尺寸很小,我们可以简单地做

int array[M][N];

(我之前从 Stackoverflow 学到了这一点,非常感谢!)

【讨论】:

  • "int array[M][N]" 不用担心泄漏,因为它是在堆栈上分配的(对吗?),但是使用原始的“new”和指针有泄漏的风险;所以我想将一些现有的容器类或快速库用于多维数组实际上更好(更安全),尤其是数值计算。
  • 谢谢!我是 C++ 新手,不知道 (int ()[N]) 和 (int ()[M][N]) 的含义是什么。它们看起来像类型。但我不确定如何正确理解它们。它们看起来也像通用表达式。
  • @HanM 嗨,这根本不是什么特别的事情,它只是类型转换为指向矩形数组的指针(也参见上面 Vlad 的第二个示例)。如果您找到一些更好的多维度数组方法,也请告诉我:)
猜你喜欢
  • 1970-01-01
  • 2013-10-14
  • 2021-07-21
  • 1970-01-01
  • 1970-01-01
  • 2011-06-30
  • 1970-01-01
  • 1970-01-01
  • 2021-04-16
相关资源
最近更新 更多