Stack Overflow Exception when declaring multidimensional arrays

那年仲夏 提交于 2019-12-02 02:17:50

Assuming for simplicity that sizeof(string) == 2 (it's probably more), you're trying to allocate (64^3)*9*2 bytes on the stack. That comes out to 4,718,592 bytes, or approximately 4.5 MiB. Most likely, you just don't have 4.5 MiB available on your stack.

Since these variables are declared in main(), you have two possible solutions:

  1. Declare them static.

  2. Declare them outside main(), as global variables.

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.

A simple solution is to use static allocation (i.e. move your arrays outside of any function, or mark them as static).

Note that if you use C++ arrays then the usage and footprint are the same but then they behave like proper containers:

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):

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.

This line:

string  reg_perm_mark_name[64][64][64]

declares 64*64*64 = 262144 strings on the stack. A std::string is typically about 32 bytes so thats about 8MB. The maximum stack size is typically about 1MB.

To declare the array dynamically you could use std::vector. Generally, multidimensional std::vectors 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::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. The use of std::array avoids too many memory allocations as they have a fixed size. I would use typedefs or using aliases to make the declaration clearer:

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!";
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!