声明多维数组时的堆栈溢出异常

时间:2015-07-11 00:58:51

标签: c++ arrays pointers multidimensional-array stack-overflow

我对编程有些新意,我遇到了声明3D和4D数组的问题。我在main函数的开头有几个这样的声明,但是我把问题缩小到了这四个:

string  reg_perm_mark_name[64][64][64];
short   reg_perm_mark_node_idex[64][64][64];
short   reg_perm_mark_rot[64][64][64][4];
short   reg_perm_mark_trans[64][64][64][3];

当我使用这些程序运行程序时,我的可执行文件中出现“System.StackOverflowException”。我更喜欢动态分配它们的方式,我现在的方式本来就是暂时的,我不知道如何正确地声明数组指针。

我在4D数组reg_perm_mark_trans中使用的4个元素是[节点索引] [区域索引] [标记索引] [xyz坐标]。此外,共有35个多维数组同时被声明。 (大多数是1D和2D)我不确定这是否有帮助。

有人能告诉我如何让这些4d数组工作,或者如何让它们用指针或向量动态分配?请说明,我还在学习。

3 个答案:

答案 0 :(得分:4)

为了简单起见sizeof(string) == 2(可能更多),你试图在堆栈上分配(64 ^ 3)* 9 * 2字节。结果是4,718,592字节,或大约4.5 MiB。最有可能的是,您的堆栈中没有4.5 MiB可用。

由于这些变量是在main()中声明的,因此您有两种可能的解决方案:

  1. 声明他们static

  2. 将它们作为全局变量在main()之外声明。

  3. 这将导致在程序启动之前分配它们,而不是在堆栈上分配它们。这两种方法的唯一区别在于它们是否在其他功能中可见。

    可能还有一种方法可以告诉编译器程序需要更多的堆栈空间,但我认为将它们设置为静态可能是更好的解决方案。如果他们使用main()以外的函数,你可能需要做其他事情。

答案 1 :(得分:2)

这一行:

string  reg_perm_mark_name[64][64][64]

在堆栈上声明64 * 64 * 64 = 262144个字符串。 std::string通常约为32字节,因此约为8MB。最大堆栈大小通常约为1MB。

要动态声明数组,您可以使用std::vector。通常,多维std::vector可能有点麻烦,在访问元素时声明单维向量并转换为单个索引通常会更好:

std::vector<std::string> reg_perm_mark_name(64*64*64);

int i = 13;
int j = 27;
int k = 7;
reg_perm_mark_name[i + 64*j + 64*64*k] = "Hello world!";

但在这种情况下,您可以使用std::vector代替std::array来为内部类型非常有效地声明多维std::vectorstd::array的使用避免了太多的内存分配,因为它们具有固定的大小。我会使用typedef或使用别名来使声明更清晰:

using StrArray = std::array<std::string, 64>;
using StrArray2D = std::array<StrArray, 64>;

std::vector<StrArray2D> reg_perm_mark_name(64);

reg_perm_mark_name[3][4][7] = "Hello world!";

答案 2 :(得分:2)

一个简单的解决方案是使用静态分配(即将数组移到任何函数之外,或将它们标记为static)。

请注意,如果您使用C ++数组,那么使用情况和覆盖区是相同的,但它们的行为就像适当的容器:

array<array<array<string,64>,64>,64> reg_perm_mark_name;

要不安全地使用动态分配,您可以写:

auto reg_perm_mark_rot = new short[64][64][64][4];
// ...
delete[] reg_perm_mark_rot;

要安全地使用它,因为C ++ 14(注意最里面的维度得到特殊处理):

auto reg_perm_mark_rot = std::make_unique<short[][64][64][4]>(64);

当然你可以使用array而不是带有动态选项的C风格数组,但是你可以使用额外的间接级别来使用数组。