简体   繁体   English

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

[英]Stack Overflow Exception when declaring multidimensional arrays

I'm somewhat new to programming in general and I've run into an issue with declaring 3D and 4D arrays. 我对编程总体上有些新意,我遇到了声明3D和4D数组的问题。 I have several declarations like this at the start of my main function, but I've narrowed the problem down to these 4: 我在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];

When I run my program with these, I get "System.StackOverflowException" in my executable. 当我用这些程序运行程序时,我的可执行文件中出现“System.StackOverflowException”。 I would much prefer a way to allocate them dynamically, The way I have it now was meant to be temporary anyway and I'm not sure how to declare array pointers properly. 我更喜欢一种动态分配它的方法,我现在拥有它的方式无论如何都是临时的,我不确定如何正确地声明数组指针。

The 4 elements I'm using in the 4D array reg_perm_mark_trans, for example, are [node index][region index][marker index][xyz coordinates]. 例如,我在4D数组reg_perm_mark_trans中使用的4个元素是[节点索引] [区域索引] [标记索引] [xyz坐标]。 Also there's a total of 35 multidimensional arrays being declared at once. 此外,共有35个多维数组同时被声明。 (most of them are 1D and 2D) I'm not sure if that helps. (大多数是1D和2D)我不确定这是否有帮助。

Can someone show me how to make these 4d arrays work or maybe how to make them dynamically allocating with pointers or vectors? 有人可以告诉我如何使这些4d数组工作或者如何使它们动态分配指针或向量? Be descriptive please, I'm still learning. 请描述一下,我还在学习。

Assuming for simplicity that sizeof(string) == 2 (it's probably more), you're trying to allocate (64^3)*9*2 bytes on the stack. 假设为了简单, sizeof(string) == 2 (可能更多),你试图在堆栈上分配(64 ^ 3)* 9 * 2字节。 That comes out to 4,718,592 bytes, or approximately 4.5 MiB. 结果是4,718,592字节,或大约4.5 MiB。 Most likely, you just don't have 4.5 MiB available on your stack. 最有可能的是,您的堆栈上没有4.5 MiB可用。

Since these variables are declared in main() , you have two possible solutions: 由于这些变量是在main()中声明的,因此您有两种可能的解决方案:

  1. Declare them static . 将它们声明为static

  2. Declare them outside main() , as global variables. 将它们声明为main() ,作为全局变量。

This will cause them to be allocated before the program starts, rather than on the stack. 这将导致在程序启动之前分配它们,而不是在堆栈上分配它们。 The only difference between the two approaches is whether they'll be visible in other functions. 这两种方法的唯一区别在于它们是否在其他功能中可见。

There may also be a way to tell your compiler that the program needs more stack space, but I think making them static is probably the better solution here. 可能还有一种方法可以告诉编译器程序需要更多的堆栈空间,但我认为将它们设置为静态可能是更好的解决方案。 If they were in a function other than main() though, you'd probably need to do something else. 如果他们在main()之外的函数中,你可能需要做其他事情。

This line: 这一行:

string  reg_perm_mark_name[64][64][64]

declares 64*64*64 = 262144 strings on the stack. 在堆栈上声明64 * 64 * 64 = 262144个字符串。 A std::string is typically about 32 bytes so thats about 8MB. std::string通常大约为32个字节,因此大约为8MB。 The maximum stack size is typically about 1MB. 最大堆栈大小通常约为1MB。

To declare the array dynamically you could use std::vector . 要动态声明数组,可以使用std::vector Generally, multidimensional std::vector s can be a bit cumbersome and it is often better to declare a single dimensional vector and convert to a single index when you access an element: 通常,多维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!";

But in this case you can declare a multi-dimensional std::vector quite efficiently by using std::array instead of std::vector for the inner types. 但是在这种情况下,通过使用std::array而不是std::vector作为内部类型,可以非常有效地声明多维std::vector The use of std::array avoids too many memory allocations as they have a fixed size. std::array的使用避免了太多的内存分配,因为它们具有固定的大小。 I would use typedefs or using aliases to make the declaration clearer: 我会使用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!";

A simple solution is to use static allocation (ie move your arrays outside of any function, or mark them as static ). 一个简单的解决方案是使用静态分配(即将数组移到任何函数之外,或将它们标记为static )。

Note that if you use C++ arrays then the usage and footprint are the same but then they behave like proper containers: 请注意,如果您使用C ++数组,那么使用和覆盖区是相同的,但它们的行为就像正确的容器:

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

To use dynamic allocation unsafely, you could write: 要不安全地使用动态分配,您可以写:

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

To use it safely, since C++14 (note that the innermost dimension gets special treatment): 要安全地使用它,从C ++ 14开始(注意最里面的维度得到特殊处理):

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

Of course you can use array instead of C-style arrays with the dynamic options, but then you would have an extra level of indirection to use the array. 当然,你可以使用array而不是带有动态选项的C风格数组,但是你可以使用额外的间接级别来使用数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM