How do i declare a 2d array using new?
Like, for a "normal" array I would:
int* ary = new int[Size]
but
int** ary = new int[sizeY][sizeX]
a) doesn't work/compile and b) doesn't accomplish what:
int ary[sizeY][sizeX]
does.
How do i declare a 2d array using new?
Like, for a "normal" array I would:
int* ary = new int[Size]
but
int** ary = new int[sizeY][sizeX]
a) doesn't work/compile and b) doesn't accomplish what:
int ary[sizeY][sizeX]
does.
Here, I have two options. The first one shows the concept of an array of arrays or pointer of pointers. I prefer the second one because the addresses are contiguous, as you can see in the image.
typedef is your friend
After going back and looking at many of the other answers I found that a deeper explanation is in order, as many of the other answers either suffer from performance problems or force you to use unusual or burdensome syntax to declare the array, or access the array elements ( or all the above ).
First off, this answer assumes you know the dimensions of the array at compile time. If you do, then this is the best solution as it will both give the best performance and allows you to use standard array syntax to access the array elements.
The reason this gives the best performance is because it allocates all of the arrays as a contiguous block of memory meaning that you are likely to have less page misses and better spacial locality. Allocating in a loop may cause the individual arrays to end up scattered on multiple non-contiguous pages through the virtual memory space as the allocation loop could be interrupted ( possibly multiple times ) by other threads or processes, or simply due to the discretion of the allocator filling in small, empty memory blocks it happens to have available.
The other benefits are a simple declaration syntax and standard array access syntax.
In C++ using new:
Or C style using calloc:
Although this popular answer will give you your desired indexing syntax, it is doubly inefficient: big and slow both in space and time. There's a better way.
Why That Answer is Big and Slow
The proposed solution is to create a dynamic array of pointers, then initializing each pointer to its own, independent dynamic array. The advantage of this approach is that it gives you the indexing syntax you're used to, so if you want to find the value of the matrix at position x,y, you say:
This works because matrix[x] returns a pointer to an array, which is then indexed with [y]. Breaking it down:
Convenient, yes? We like our [ x ][ y ] syntax.
But the solution has a big disadvantage, which is that it is both fat and slow.
Why?
The reason that it's both fat and slow is actually the same. Each "row" in the matrix is a separately allocated dynamic array. Making a heap allocation is expensive both in time and space. The allocator takes time to make the allocation, sometimes running O(n) algorithms to do it. And the allocator "pads" each of your row arrays with extra bytes for bookkeeping and alignment. That extra space costs...well...extra space. The deallocator will also take extra time when you go to deallocate the matrix, painstakingly free-ing up each individual row allocation. Gets me in a sweat just thinking about it.
There's another reason it's slow. These separate allocations tend to live in discontinuous parts of memory. One row may be at address 1,000, another at address 100,000—you get the idea. This means that when you're traversing the matrix, you're leaping through memory like a wild person. This tends to result in cache misses that vastly slow down your processing time.
So, if you absolute must have your cute [x][y] indexing syntax, use that solution. If you want quickness and smallness (and if you don't care about those, why are you working in C++?), you need a different solution.
A Different Solution
The better solution is to allocate your whole matrix as a single dynamic array, then use (slightly) clever indexing math of your own to access cells. The indexing math is only very slightly clever; nah, it's not clever at all: it's obvious.
Given this
index()
function (which I'm imagining is a member of a class because it needs to know them_width
of your matrix), you can access cells within your matrix array. The matrix array is allocated like this:So the equivalent of this in the slow, fat solution:
...is this in the quick, small solution:
Sad, I know. But you'll get used to it. And your CPU will thank you.