For a known-constant-size arrays you can do this
auto shared_array = std::shared_ptr<int[3][3][3]>();
If only the first dimension is not a compile-time constant, you can do this:
auto shared_array = std::shared_ptr<int[][3][3]>(N); // N is a variable
(Caution: you need a cutting edge version of gcc or clang to compile this, and at least -std=c++20
; the latest msvc /std:c++latest
supports this)
(There is also a unique_ptr
version of the second variant, but not of the first variant. Why is it so is beyond the scope of this answer).
If a dimension other than the first is not a compile-time constant, then things get really complicated. Unlike Java, C doesn't have true multidimensional arrays. What to do?
One can use a multi-level std::vector
in a pinch:
auto multi_vector = std::vector<std::vector<std::vector<int>>>();
multi_vector.resize(N);
for (auto& elem: multi_vector)
{
elem.resize(M);
for (auto& next_level_elem: elem)
{
next_level_elem.resize(K);
}
}
You can tell this is not a most pretty solution, but write it once, hide it in a function, and forget about it. You can also write something like this to the same effect:
auto array =
std::vector<std::vector<std::vector<int>>>(N,
std::vector<std::vector<int>>(M,
std::vector<int>(K)));
which may or may not be more readable, depending on who's reading (it's less readable for me but YMMV).
You can also use an array of unique_ptr
s to arrays in much the same way but I'll leave it to you to figure it out.
The real problem with this solution is not that it is ugly, but that it is very, very inefficient. The triple indirection is a cache killer.
The real solution is to use a dedicated third-party multidimensional array library like Boost.MultiArray or Eigen.Tensor (note this is unsupported). Or, when you are a really seasoned C++ programmer, roll your own.
#include <boost/multi_array.hpp>
using boost3arrType = boost::multi_array<int, 3>;
using boost3shapeType = boost::array<boost3arrType::index, 3>;
auto x = boost3arrType(boost3shapeType{{2,3,4}});
x[0][1][2] = 42;
#include <eigen3/unsupported/Eigen/CXX11/Tensor>
auto eigenTensor3 = Eigen::Tensor<int, 3>(2, 3, 4);
eigenTensor3(0,1,2) = 42;
No support for eigenTensor3[0][1][2]
syntax.
Finally, if you are enrolled in a really crappy C++ course and your professor would not accept anything he couldn't find in the 1990 Stroustrup book, there's always this. You should not use this method for anything except your assignment that disallows all of the above.