I'm somewhat new to programming in general and I've run into an issue with declaring 3D and 4D arrays. I have several declarations like this at the start of my main function, but I've narrowed the problem down to these 4:
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. 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]. Also there's a total of 35 multidimensional arrays being declared at once. (most of them are 1D and 2D) I'm not sure if that helps.
Can someone show me how to make these 4d arrays work or maybe how to make them dynamically allocating with pointers or vectors? Be descriptive please, I'm still learning.
This line:
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, multidimensionalstd::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:But in this case you can declare a multi-dimensional
std::vector
quite efficiently by usingstd::array
instead ofstd::vector
for the inner types. The use ofstd::array
avoids too many memory allocations as they have a fixed size. I would use typedefs or using aliases to make the declaration clearer: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:Declare them
static
.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:
To use dynamic allocation unsafely, you could write:
To use it safely, since C++14 (note that the innermost dimension gets special treatment):
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.