Allocating multi-dimensional arrays in C++
July 23rd, 2003 at 1:35 pmUpdated on 04.06.2010
Allocating multi-dimensional arrays in C++ (and C) is not a trivial task for newbies, and many find it difficult. The concept itself isn’t really that hard to understand, but the cryptic syntax of C++ can sometimes make it far from obvious.
The important point to understand here is that in C++, a multi-dimensional array is actually an array of arrays. Thinking in these terms, the task becomes quite easy. It is best to illustrate this with an example:
#include <iostream>
#include <cstring>
using namespace std;
int main(int argc, char *argv[])
{
unsigned i;
// Declaration of the two-dimensional array
// as a pointer to pointer
//
char** array_2D;
unsigned ROWS = 10;
unsigned COLUMNS = 10;
// Allocate "main" array
//
array_2D = new char*[ROWS];
// Allocate each member of the "main" array
//
for (i = 0; i < ROWS; ++i)
array_2D[i] = new char[COLUMNS];
// Fill the 6th element with a string and
// print it out
//
strcpy(array_2D[5], "Hey there");
cout << array_2D[5] << endl;
// Deletion is performed in reversed order.
// Pay special attention to the delete[]
// operator which must be used to delete
// arrays (instead of the "simple" delete)
//
for (i = 0; i < ROWS; ++i)
delete[] array_2D[i];
delete[] array_2D;
return 0;
}
In this example, an 2-dimensional array of char is created. As you probably know, an array of char is usually used in the role of a text string in C, so a 2-dimensional array is then an array of C strings.
Dynamic allocation and reclamation of multi-dimensional arrays is not an entirely trivial task. It is also quite "dangerous", as memory leaks and/or buffer overflows may be easily produced. If all you need is an array of character strings, it is highly advised to use a vector of strings from the C++ standard library.
Related posts:

November 24th, 2006 at 13:27
Nice article about multidimensional arrays! I was looking for something like this. Your example is very clear and avoids confusing by using a simple delete [] array[i] instead of pointer notation.
March 18th, 2007 at 00:32
very nice and smart
was looking for smth like that for all day
April 27th, 2007 at 04:42
Thanks Eli, this worked first time.
August 27th, 2007 at 15:32
People incapable of this shouldnt code anyways.
August 3rd, 2008 at 17:25
or do it in one shot instead:
// the parens are necessary
char (*p2d)[COLUMNS] = new char[ROWS][COLUMNS];
p2d[1][1] = ‘x’;
delete [] p2d; // don’t forget the []
you can easily see that constructors and destructors are properly called by allocating an array of a simple class that writes output from them.
August 7th, 2008 at 16:48
Ah!, Finally thank you very much!.
Was looking all over for this.
I actually tried it before I found this, just didn’t think of the need for the reverse deallocation.
It is kinda weird that, my beginners book(Which i am done with!), GameDev, and some other C++ sites, which include beginner guides did not include this(Or they just made it really hard to find)
Well thank you again, now i can continue.
April 12th, 2009 at 08:24
There are a few problems with this.
1. There are no include files actually specified. This means
std::strcpy()has somehow become available in the program without actually including anything. Let’s not use C89′s implicit function declarations. I have no idea howstd::coutandstd::endlare used.2. It makes use of
using namespace std;in the global scope. For the purposes of teaching programmers new to C++, this is wrong. Even if it wasn’t for programmers new to C++, it would be wrong.3. Your use of compile time constants sort of negates the point of this post. Having used compile time constants, it makes more sense to simply allocate it on the stack. This would be fine if you commented that you’re only using compile time constants for the purposes of illustration. Without this comment, new programmers will misunderstand the point of dynamic allocation and needlessly create memory leaks.
4. You left out an alternative format for dynamic allocation of N dimensional arrays. This one requires that the final most dimension be a compile time constant:
Where
dim2must be a compile time constant. This code allocates an array with dimensiondim1ofint[dim2]. The difference between this and the one you use in this post is that this form allocates a form of /exactly/dim1xdim2. The one you use allocates an array with dimensiondim1of pointers to int, and then an array with dimensiondim2of type int is assigned to each pointer. Thinking carefully, one realizes that the latter approach can create a form similar to the following.Where each
1signifies an index in the structure.June 4th, 2010 at 11:10
@zoom,
1. Typo with include headers – fixed, thanks.
2. This is a debatable point. Personally I think it’s valid to do
using namespace stdin your main file.3. You’re right – I removed the const cualifiers of the relevant variables
4. Yes, but my intention was specifically for the more general array of arrays that, as you said, can also be used to create “ladder” arrays