For allocating space for a 2D array, you have use "double" pointer (a.k.a. pointer-to-pointer). Just as a 1D array is equivalent to a "single" pointer, a "double" pointer is equivalent to a 2-D array. I'll try to explain this with some examples below. Example-1: First and foremost you need to internalise that, essentially, there is no difference between a pointer and an array (with a few caveats). The name of the array is the pointer to the first element of the array. int *p; // You have a pointer which can point to a location which stores an int int arr[10]; p = arr; // This makes 'p' point to the first element of arr, i.e., p = &arr[0] // Which implies p[2], arr[2], *(p+2) will give you access to the SAME element, and so on // This also, implies that if you had a pointer, you might as well do (p+1), (p+2), ... to make it point to next elements in the memory, // regardless of the fact whether there actually are any elements or not. (It's a different issue that in the above example, there were 10 elements.) // NOTE: Trying to access a memory space which was not allocated by your program, will result in the operating system crashing your program Example-2: Imagine if you had to write a function which allocates space for N integers at run-time and returns back that array. int* allocate(int N) { int *p; // 'p' is a pointer to an address which stores an int // From example-1, you can see how 'p' can be used to point to a single integer or an array of integers. p = new (int) [N]; // This allocates a contiguous space for 'N' integers, and returns the address of the first element // Do whatever you want to do with 'p' as you would with an array return p; } Example-3: Now, let's take it to the next level with 2D arrays. int** allocate(int R, int C) { int **p; // 'p' is a pointer to pointer -- meaning 'p' points to an address which stores another pointer to int // Again from example-1 and example-2, you can imagine how, 'p' might point to a single pointer or an array of pointers // Allocate space for 'R' pointers, each of which will be a pointer to an int // You can imagine how each of those pointers can be used to represent an array from example-1 and 2 p = new (int *)[R]; // Now make each of these R pointers, point to C int's // This way you are creating R rows and C columns. for (int i = 0; i < R; i++) { // p[i] or (p+i) give you access to each of those pointers in the array of pointers p[i] = new (int) [C]; } // Now you can do whatever you want with p, treating it as equivalent to p[R][C] return p; }