You probably just know how to return the pointer, if you can't return a higher dimension array.
The trick is to return an object. So define your 2D array as an object; you can use std::array<std::array<T, NCOLS>, NROWS>, or a vector equivalent or a struct/class. Then just return that.
If you stick with pointers, you'll loose dimension sizes.
if you know the dimensions (compile time constant 2d array?) you can return it as 1d and cast it back with some ugly tricks. But that is so very C and weird code.
There are a lot of reasons why 1d mapped to 2d is easier to work with (you manually index the 1d to make it '2d' exactly the same way C does it).
if you need to see the casting junk I can figure it out again, but its not a good idea.
To return a 2D array from a function in C++, you need to declare the function with the return type as a pointer to an array
That doesn't return a 2D array. It returns a pointer and the memory to which it refers must still be valid after the function returns (eg using static as above). But this isn't 'returning an array' - just a pointer. As has been mentioned above, in c/C++ you can't directly return a c-style array from a function.
The array itself is declared as a static variable, so it persists between function calls.
I've seen some functions that return a pointer to a static local object like this but there are reasons why this is not more common. If the object can be modified (by the caller or by the function itself) then it's not thread-safe and could be surprising if you don't know or forget about this and call the function to get two different objects when in fact they are one and the same.
Surprise, surprise!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#include <iostream>
#include <iomanip>
#include <ctime>
int main()
{
std::time_t now = std::time(nullptr);
std::time_t later = now + 8640000;
std::tm* n = std::localtime(&now);
std::tm* l = std::localtime(&later);
std::cout << "Now: " << std::put_time(n, "%Y-%m-%d") << "\n";
std::cout << "Later: " << std::put_time(l, "%Y-%m-%d") << "\n";
}
Now: 2023-07-06
Later: 2023-07-06
Just reordering the lines a bit makes it output correctly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#include <iostream>
#include <iomanip>
#include <ctime>
int main()
{
std::time_t now = std::time(nullptr);
std::tm* n = std::localtime(&now);
std::cout << "Now: " << std::put_time(n, "%Y-%m-%d") << "\n";
std::time_t later = now + 8640000;
std::tm* l = std::localtime(&later);
std::cout << "Later: " << std::put_time(l, "%Y-%m-%d") << "\n";
}
#include <iostream>
usingnamespace std;
//===================================================================
template<typename T>
T** allocate( int rows, int cols )
{
T **a = new T*[rows];
a[0] = new T[rows * cols];
for ( int r = 1; r < rows; r++ ) a[r] = a[r-1] + cols;
return a;
}
//===================================================================
template<typename T>
void deallocate( T **a )
{
delete [] a[0];
delete [] a;
}
//===================================================================
template<typename T>
void print( T **a, int rows, int cols )
{
for ( int r = 0; r < rows; r++ )
{
for ( int c = 0; c < cols; c++ ) cout << a[r][c] << '\t';
cout << '\n';
}
}
//===================================================================
int main()
{
constint ROWS = 3, COLS = 5;
double **a = allocate<double>( ROWS, COLS );
for ( int r = 0; r < ROWS; r++ )
for ( int c = 0; c < COLS; c++ ) a[r][c] = 10 * r + c;
print( a, ROWS, COLS );
deallocate( a );
}
template<typename T>
T** allocate( int rows, int cols )
...
Yes - but why in C++? This is very c-ish. I know the OP said no vector - but why? In C++ you'd either use a std::vector or a std::array - which can be returned from a function. And if you did require a 2d array of contiguous memory, you'd have a class that supported that which could be returned from a function...
Sorry, @seeplus, I just created that function so that I could call it roughly the way I would in Fortran. (Except that Fortran very kindly deallocates for you when it goes out of scope). For example, https://onlinegdb.com/k8zAxfY2u
There are a lot of advantages - particularly when working in MPI or other parallel paradigm - from having multidimensional arrays with contiguous storage. vector<<vector>> just doesn't do that, and why create a new class when you don't need to?