Home > Net >  c 3d array function returns
c 3d array function returns

Time:11-09

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;
}
  • Related