Reputation: 1031
I want to create a dynamic 2d array in a separate function. The size of the array will be determined at runtime.
Pass an array directly:
void foo(int **arr,int width,int height)
{
arr=new int*[width];
for(int i=0;i<height;i++)
{
arr[i]=new int[height];
}
//fill...
}
...
int** array;
foo(array)
doesn't seem to work
Pass an array via a pointer
void foo(int ***arr,int width,int height)
{
*arr=new int*[width];
for(int i=0;i<height;i++)
{
*arr[i]=new int[height];
}
//fill...
}
...
int **array;
foo(&array)
doesnt seem to work either
How do I do that?
Upvotes: 0
Views: 65
Reputation: 35440
Let's assume you have to create 2d arrays this way (with an int**
).
Instead of trying to pass pointers, return the value that denotes the 2d array.
Second, your code had a bug in that you were looping over the height
when you should be looping over the width
. Your code would have gone into undefined behavior if height > width
.
Third, I don't know if you meant width
to be the first dimension or height
to be the first dimension, so let's assume that what you wrote is what you meant, i.e. width
is the first dimension and height
is the inner dimension.
int **foo(int width, int height)
{
int **arr = new int*[width];
for(int i=0; i<width; i++)
arr[i]=new int[height];
return arr;
}
//....
int width = 10, height = 10;
int** array = foo(width, height);
Then you have to write code to delete the allocated data:
for (int i = 0; i < width; ++i)
delete [] array [i];
delete [] array;
Now having said the above, and the above should work, a more optimal version is found here, where the data is one contiguous block instead of separate allocated blocks. This reduces the number of times new[]
and delete []
would need to be called.
Upvotes: 1
Reputation: 2007
I think that your "problem" is caused by ignoring operator precedence
Second code you posted seems to have mistake on line with:
*arr[i]=new int[height];
which should be
(*arr)[i]=new int[height];
Also, as other pointed out, working with raw pointers could sometimes be pretty evil (like in your example with Pointer to Pointer to Pointer), raw pointers could also cause some problems with memory leaks, dangling pointers,etc. Use something "more practical" like std::vector
or some of the other STL containers.
(Note: By term "STL", I mean part of Standard library based on STL)
Upvotes: 2
Reputation: 20396
Generally speaking, multidimensional arrays should never, never be created like this. You should be using a single array wrapped in an object that provides row, column, table, etc. access using the operator()
function.
You should also never, never be using raw pointers (except in weird, extenuating circumstances) which is why I'm using STL's std::vector
class to implement your code.
class array_2d {
public:
array_2d(size_t width, size_t height) :
width(width),
height(height),
_array(width * height)
{}
int & operator()(size_t x, size_t y) {
return _array[y * width + x];
}
const int & operator()(size_t x, size_t y) const {
return _array[y * width + x];
}
std::pair<size_t, size_t> get_size() const {
return std::make_pair<size_t, size_t>(width, height);
}
private:
size_t width, height;
std::vector<int> _array;
};
int main() {
array_2d my_array(5,5);
my_array(3,3) = 7;
std::cout << my_array(3,3) << std::endl;
return 0;
}
====
7
There's a lot of stuff I didn't include (and the code would be significantly more complex if you were to implement this as a raw pointer) but this is a far superior way to write a 2-dimensional (or more dimensions, if you need it) array.
Upvotes: 1