So i've got this 3 dimensional array that looks like this:
int map[100][100][100];
and I want to use it as a return type for a function, whether as a pointer or whatever like so:
int* World::CreateCell() {
int map[100][100][100];
return map;
}
However I cannot find the appropriate return type for a 3d array, it will not let me use an int* like you can for a 2D array.
Even things like this don't work:
int a[100][100][100];
int* b = a;
VS seems to think the data type is int*(100)(100)
but that makes no sense and doesn't work.
For what it's worth, I've googled this and seen no solutions. Thank you
CodePudding user response:
First you should
Never return a reference or a pointer to a local non-static variable.
Now coming to your question:
I want to use it as a return type for a function, whether as a pointer or whatever like so.However I cannot find the appropriate return type for a 3d array.
This(below) is how you can do it for a 3D array. Basically there are 2 ways to solve this:
Method 1
//CreateCell is a function that returns a pointer to a 3D array of the size 100,100,100
int (*CreateCell())[100][100][100] {
int map[100][100][100];
return ↦
}
Method 1 works as can be seen here.
Method 2
//CreateCell is a function that returns a pointer to a 3D array of the size 100,100,100
auto CreateCell() -> int(*)[100][100][100] {
int map[100][100][100];
return ↦
}
Method 2 uses trailing return type and works as can be seen here.
Note
Both methods return a pointer to a local variable which must be avoided. I have given/written the answer just so that you can see how to return a pointer for a 3D array as you desired. You can instead create and return a 3D `std::vector` by value.CodePudding user response:
Since you want 3D C-style array, you need to have a pointer to a pointer to a pointer, i.e., int***
. Also, you need to allocate the memory if you use a creation function like this. Otherwise, you return the statically allocated memory from that function.
Here is a quick example of how to do it:
#include <iostream>
static int*** create_cell() {
constexpr std::size_t n = 100;
int*** map = new int**[n];
for (std::size_t i = 0u; i < n; i) {
map[i] = new int*[n];
for (std::size_t j = 0u; j < n; j) {
map[i][j] = new int[n];
}
}
return map;
}
static void delete_cell(int***& map) {
constexpr std::size_t n = 100;
for (std::size_t i = 0u; i < n; i) {
for (std::size_t j = 0u; j < n; j) {
delete[] map[i][j];
}
delete[] map[i];
}
delete[] map;
}
int main()
{
int*** a = create_cell();
a[0][0][0] = 1;
std::cout << "a[0][0][0] = " << a[0][0][0] << std::endl;
delete_cell(a);
return 0;
}
It depends on your use case: BUT for modern c you can ease your life using containers from the stl
such as std::vector
and std::array
. Check here for reference: std::array and std::vector
For example, you can define your 3D types:
#include <array>
#include <vector>
using vector_3d = std::vector<std::vector<std::vector<int>>>;
using array_3d = std::array<std::array<std::array<int, 100>, 100>, 100>;
and then use them as:
array_3d b;
b[0][0][0] = 1;
std::cout << "b[0][0][0] = " << b[0][0][0] << std::endl;
CodePudding user response:
Consider using a simple wrapper around your matrix:
struct Wrapper { int Mat[100][100][100] = {0}; };
The signature would then become something like:
Wrapper *foo(...) { ... }
Here is simple working example:
#include <iostream>
struct Wrapper { int Mat[100][100][100] = {0}; };
Wrapper *inc(Wrapper *w)
{
for (int i=0;i<100;i )
for (int j=0;j<100;j )
for (int k=0;k<100;k )
w->Mat[i][j][k] = (i j k);
return w;
}
int main(int argc, char **argv)
{
Wrapper w;
Wrapper *out = inc(&w);
std::cout << out->Mat[5][6][7] << "\n";
return 0;
}