如果直接在栈上创建维数很高的多维数组,会有爆栈的风险。
在 stackflow 上搜索了一个回答,感觉很新颖,示例如下。请问下大家有其他方法能简单地在堆上创造多维数组吗?
#include <memory>
struct Foo
{
int arr[100][200][100];
};
int main()
{
auto foo = std::make_unique<Foo>(); // allocate on the heap
auto& arr = foo->arr;
arr[1][2][3] = 42;
return 0;
}
1
codehz 2022-08-08 22:52:18 +08:00 via iPhone 1
直接用 std::array 不好吗)
|
3
BrettD 2022-08-08 23:00:19 +08:00 1
|
4
codehz 2022-08-08 23:00:32 +08:00 via iPhone 1
@wisefree 你 new std::array 不就可以了?,或者用 unique_ptr 装最外层
|
5
yyt6801 2022-08-09 00:17:56 +08:00 via Android
new
|
6
darer 2022-08-09 00:22:33 +08:00
自定义类封装一维数组,重载()
|
7
ysc3839 2022-08-09 00:40:06 +08:00 via Android 1
用 C 的连续多维数组主要还是想用多维转成偏移量的语法糖吧,如果一定要用这个语法糖的话那只有楼主说的这种这种方法了。否则只能依赖 C++的特性,比如 std::array 容器嵌套。
|
8
cnbatch 2022-08-09 00:53:56 +08:00 1
我之前也有这样的需求,但需要更加灵活,大小并非编译时固定,而是类似于 C 语言的那种 VLA (正好就是曾经有望入标准库但最终被放弃的 std::dynarray ),于是仿照 std::dynarray 和 std::vector 的 API 弄了个简单的实现:
https://github.com/cnbatch/dynarray 默认在堆上分配,而非栈上分配。 我在里面提供了两种写法的版本。 写法 1 (位于 vla_nest/dynarray.hpp ): int x = 100, y = 200; int value = 5; vla::dynarray<vla::dynarray<int>> vla_array(x, y, value); // 相当于 int[x][y],全部初始化为 5 写法 2 (位于 vla_cleanlily/dynarray.hpp ): int x = 100, y = 200; int value = 5; vla::dynarray<int, 2> vla_array(x, y, value); // 意思同上例,其中<int, 2>的意思是,创建 int 类型的二维数组 写法 1 看起来更“传统”一点,这是我最初的习惯。后来有人跟我说弄成写法 2 这种更加美观,我想了想觉得很对,于是就加了这个版本。 创建完成后的用法就跟普通数组无异,都是 vla_array[3][1] = 100; vla_array[5][5] = vla_array[2][2]; |
9
yanqiyu 2022-08-09 09:04:22 +08:00 1
为什么不直接 auto arr = std::make_unique<int[][100][100]>(100)
|
11
ColorfulBoar 2022-08-16 12:22:48 +08:00 1
在不在堆上其实不是个问题……总的来说建议不要用“多维数组”,然后把它分成「一坨数据」和「访问方式」两部分,这样不管是写起来还是用起来还是做优化都比较方便(就像 graphics API 里面总是把 texture 和 view 分开一样)。
举个只用标准库的朴素例子: (没有 C++23 自己去毛一个 https://github.com/kokkos/mdspan |