how do i declare a two d array using new?
like for a "normal" array i would:
int* ary = new int[Size]
but
int** ary = new int[sizeY][sizeX]
a) deosn't work/compile and b) doesn't acomplish what:
int ary[sizeY][sizeX]
does.
how do i declare a two d array using new?
like for a "normal" array i would:
int* ary = new int[Size]
but
int** ary = new int[sizeY][sizeX]
a) deosn't work/compile and b) doesn't acomplish what:
int ary[sizeY][sizeX]
does.
I recommend reading what C++ FAQ Lite says on the subject. Allocating (and more importantly, properly freeing) a multi-dimensional array using new
can be tricky. Also, the next three FAQs in sequence from the one I linked are a good read. They'll give you tips on how to turn your array into its own class (enabling RAII, among other things), and an introduction to genericity using templates.
A dynamic 2D array is basically an array of pointers to arrays. You should initialize it using a loop:
int** ary = new int*[sizeX];
for(int i = 0; i < sizeX; ++i)
ary[i] = new int[sizeY];
Try doing this:
int **ary = new int[sizeY];
for (int i = 0; i < sizeY; i++)
ary[i] = new int[sizeX];
int** ary = new int[sizeY][sizeX]
should be:
int **ary = new int*[sizeY];
for(int i = 0; i < sizeY; ++i) {
ary[i] = new int[sizeX];
}
and then clean up would be:
for(int i = 0; i < sizeY; ++i) {
delete [] ary[i];
}
delete [] ary;
EDIT: as Dietrich Epp pointed out in the comments this is not exactly a light weight solution. An alternative approach would be to use one large block of memory:
int *ary = new int[sizeX*sizeY];
// ary[i][j] is then rewritten as
ary[i*sizeY+j]
Don't. Unless you have good reason, use std::vector<std::vector < int> > instead. Memory management will be far less error prone.
Edit: If you start to run into issues with the memory being non-contiguous, such as pointed out in the comments by Dietrich Epp, you could switch to using std::vector<int> and allocate (rows * columns) elements. You can then get a hold of the first element of this vector (&v[0]) and use the techniques in the other answers to treat it as a normal int[][]. However I would only do this if you actually profiled your code and saw that the non-contiguous memory was causing performance problems. It would likely only be an issue if you had a very large 2-D array. At least that is my guess. Again, profiling is the only real way to know.
The main point of my answer was to let vector do the memory management for you.
typedef is your friend
In C++ using new:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
typedef double (array5k_t)[5000];
array5k_t *array5k = new array5k_t[5000];
array5k[4999][4999] = 10;
printf("array5k[4999][4999] == %f\n", array5k[4999][4999]);
return 0;
}
Or C style using calloc:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
typedef double (*array5k_t)[5000];
array5k_t array5k = calloc(5000, sizeof(double)*5000);
array5k[4999][4999] = 10;
printf("array5k[4999][4999] == %f\n", array5k[4999][4999]);
return 0;
}
I presume from your static array example that you want a rectangular array, and not a jagged one. You can use the following:
int *ary = new int[sizeX * sizeY];
Then you can access elements as:
ary[y*sizeX + x]
Don't forget to use delete[] on ary
.
This question was bugging me - it's a common enough problem that a good solution should already exist, something better than the vector of vectors or rolling your own array indexing.
When something ought to exist in C++ but doesn't, the first place to look is boost.org. There I found the Boost Multidimensional Array Library, multi_array
. It even includes a multi_array_ref
class that can be used to wrap your own one-dimensional array buffer.