Allocating multi-dimensional arrays in C++

July 23rd, 2003 at 1:35 pm

Updated 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:

  1. Are pointers and arrays equivalent in C?
  2. Initialization of structures and arrays in C++
  3. Pointers vs. arrays in C, part 2(D)
  4. Pointers to arrays in C
  5. Reading C type declarations

8 Responses to “Allocating multi-dimensional arrays in C++”

  1. Evert MouwNo Gravatar Says:

    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.

  2. lenNo Gravatar Says:

    very nice and smart :) was looking for smth like that for all day :D

  3. Bill FrostNo Gravatar Says:

    Thanks Eli, this worked first time.

  4. MooNo Gravatar Says:

    People incapable of this shouldnt code anyways.

  5. supersaurusNo Gravatar Says:

    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.

  6. MikaNo Gravatar Says:

    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.

  7. zoomNo Gravatar Says:

    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 how std::cout and std::endl are 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:

    int **arr = new int[dim1][dim2];

    Where dim2 must be a compile time constant. This code allocates an array with dimension dim1 of int[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 dimension dim1 of pointers to int, and then an array with dimension dim2 of type int is assigned to each pointer. Thinking carefully, one realizes that the latter approach can create a form similar to the following.

    1 1 1 1 1 1 1
    1 1 1 1 1 1
    1 1 1 1 1
    1 1 1 1 1 1 1

    Where each 1 signifies an index in the structure.

  8. elibenNo Gravatar Says:

    @zoom,

    1. Typo with include headers – fixed, thanks.
    2. This is a debatable point. Personally I think it’s valid to do using namespace std in 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