I want to return a 3-dimensional array from a user-defined function into my main
function.
Let's consider a simple example for any particular values of a
, b
and c
arrays;
int*** my_function(int a[], int b[], int c[])
{
for (int i = 0; i < 2; i++)
{
for (int j; j < 2; j++)
{
for (int k; k < 2; k++)
{
array[i][j][k] = a[i] * b[j] * c[k];
}
}
}
return array
}
Returning Arrays of Different SizesWe can do this by using Application. Caller which gives us a Range object, as long as our function is called from a cell. This range is the range of cells passed into the function. If CallerRows > 1 then a column is being passed into the function.
#include <iostream> template<std::size_t M, std::size_t N, std::size_t O> void func(int (&arr3d)[M][N][O]) { // some a, b, c for (std::size_t i = 0; i < M; ++i) { for (std::size_t j = 0; j < N; ++j) { for (std::size_t k = 0; k < O; ++k) { arr3d[i][j][k] = a[k] * b[k] * c[k]; std::cout << arr3d[i][j][k] << " "; // to ...
Return Array from Functions in C++ C++ does not allow to return an entire array as an argument to a function. However, you can return a pointer to an array by specifying the array's name without an index.
Just a remark: an int ***
is not suited to return a 3D array. At most it can be used to return a pointer to an array of pointers to arrays of pointers.
And as raw arrays are not first class elements in C++ language, you cannot return an array from a function in a simple an natural way.
What can be done ?
The C++ simple way:
Do not use raw arrays but std::array
is the size if fixed at compile time, or std::vector
if it is not. You can then build (and return vectors of vectors or std::array
of std::array
. Beware a vector of vectors is like an array of pointers: the data is not required to be contiguous, so it is not equivalent to a 3D array. Here, assuming fixed sizes:
std::array<std::array<std::array<int, 2>, 2>, 2> my_function(int a[], int b[], int c[])
{
std::array<std::array<std::array<int, 2>, 2>, 2> array;
...
return array;
}
A custom container (still modern C++)
If you need to simulate a 3D contiguous container in C++ and have it to behave like a normal object (that can be returned from a function), you will have to build a custom container and its accessor methods. It is not extremely complex, yet it is far from trivial. If you want to go that way, my advice is to use a (1D) vector as the underlying storage to not be bothered with the copy, move, destruct problem with raw allocated storage.
The C-ish way (with raw arrays).
Multi-dimensional arrays must have all their dimensions but the last one defined at compile time. Once this is said, you still find the 3 common C storage ways: static storage (can be safely returned, but is not thread safe), allocated storage (thread safe, but caller will be responsable for freeing it), caller provided (the caller is responsable for creating the array and pass it to the callee function. I will show you the 3rd way here
typedef int (*int3D)[2][2];
int3D my_function(int a[], int b[], int c[], int3D array) {
{
for(int i=0; i<2; i++)
{
...
}
return array;
}
Usage:
int arr[2][2][2];
int3D arr3D = my_function(a, b, c, arr);
// after the call, arr3D == arr is true
You can use std::array
.
If the sizes are compiled time known, I would suggest having std::array
, by which you could get contiguous memory layout.
#include <iostream>
#include <array>
#include <algorithm> // std::generate
// alias for the required array
using Array3D = std::array<std::array<std::array<int, 2>, 2>, 2 >;
Array3D func()
{
Array3D arr3d;
std::array<int, 2> a{ 10, 20 }, b{ 10, 20 }, c{ 10, 20 }; // some a, b, c
// iterate through the arrays to initialize them!
auto input = 1u;
for (std::array<std::array<int, 2>, 2> & array2D : arr3d) // or auto& array2D: arr3d
for (std::array<int, 2> & arr : array2D) // or auto& arr: array2D
std::generate(arr.begin(), arr.end(), [&input] { return input++; });
// for array multimplications!
for (std::array<std::array<int, 2>, 2> & array2D : arr3d) // or auto& array2D
{
for (std::array<int, 2> & arr : array2D) // or auto& arr
{
auto arrIndex = 0u;
for (int& ele : arr)
{
ele = a[arrIndex] * b[arrIndex] * c[arrIndex];
++arrIndex;
std::cout << ele << " "; // to print the element!
}
}
}
return arr3d; // return the array like this!
}
Alternatively using the templated function (with sizes as non-template parameters), you could even pass the array3d
by reference and do the calculations just you shown above!
#include <iostream>
template<std::size_t M, std::size_t N, std::size_t O>
void func(int (&arr3d)[M][N][O])
{
// some a, b, c
for (std::size_t i = 0; i < M; ++i)
{
for (std::size_t j = 0; j < N; ++j)
{
for (std::size_t k = 0; k < O; ++k)
{
arr3d[i][j][k] = a[k] * b[k] * c[k];
std::cout << arr3d[i][j][k] << " "; // to print the element
}
std::cout << "\n";
}
std::cout << "\n";
}
// do not need to return!
}
A better alternative to using pointers is to use std::vector
as that will take care of the details of memory allocation and deallocation.
How to initialize 3D vector?
3D vector is simply a vector containing two other vectors inside it. So, if you want to initialize a 3D vector of size X * Y * Z with a value A. Then it can be done as:
vector<vector<vector<int> > > vec (X,vector<vector<int> >(Y,vector <int>(Z,A)))
How to return it from a function?
You can see how to return it from the below example.
vector<vector<vector<int> > > sample_function()
{
//sample code
return vec;
}
As others mentioned, you can use std::array
or std::vector
but a simple way is to pass the array to your function as a parameter (instead of returning). sth like this:
void your_function(int array[2][2][2], /* other parameters */) {
// body
}
And use it like this:
int main() {
int arr[2][2][2];
your_function(arr, /* other arguments */);
// now do what you want with arr
}
I have got exactly what you wanted
#include <iostream>
using namespace std;
int** form_2d_array(int l, int b)
{
int **A = new int *[b];
for (int i = 0; i < b; i++)
A[i] = new int[l];
return A;
}
int*** form_3d_array(int l, int b, int h)
{
int ***A = new int **[h];
for (int i = 0; i < h; i++)
A[i] = form_2d_array(l,b);
return A;
}
int main()
{
int ***array;
int l,b,h;
l=3;b=5;h=3;
array=form_3d_array(l,b,h);
for (int i = 0; i < l; i++)
{
for (int j=0; j < b; j++)
{
for (int k=0; k < h; k++)
{
array[i][j][k] = i+j+k;
}
}
}
for (int k=0; k < h; k++)
{
cout<<"Printing "<<k+1<<"th matrix\n";
for (int i = 0; i < l; i++)
{
for (int j=0; j < b; j++)
{
cout<<array[i][j][k]<<" ";
}
cout<<endl;
}
cout<<endl;
}
return 0;
}
The 2d array function returns a 2d array and 3d array function returns a 3d array.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With