How does a pointer to a pointer correspond to a 2D array? - c++

I know this question was probably asked before, but I don't understand it in this context:
Here's the code I'm trying to examine, I'll comment it. Please let me know where I'm wrong
int **A; // declaring a pointer to a pointer
A = new int*[n]; // assigning that pointer to a newly-allocated
// space (on the heap) for an array
// of [size n] of pointers to integers
for (i = 0; i < n; ++i) // looping from 0 to n-1
A[i] = new int[n]; // assigning each slot's pointer to a
// new array of size n?
for (i = 0; i < n; ++i) // loop through all the rows
for (j = 0; j < n; ++j) // loop through each column for the current row
A[i][j] = 0; // assign the value to 0
Please let me know where I'm wrong. I don't understand anything from A = new int*[n]; I'm just trying to figure it out using common sense but I'm having troubles.
Thank you!

Your code and comments are correct. To clear up the confusion about pointers:
A 2D array is simply an array of arrays.
In order to allow the arrays to have a dynamic size (i.e. size n not known at compile time), an array of pointers is created. Each pointer in the array itself points to an array of ints.
The resulting structure is very similar to an array of arrays - it's an array of pointers to arrays. The pointers are there simply because you cannot have e.g. int a[n][n]; at compile time because the size is not known.
Here's a diagram of this:
> [ ] //">" is a pointer, pointing at an array ([ ])
[ ] [ ] [ ]
> [ ^ ^ ^ ] // The array is an array of pointers "^", each of which points to an array

What's an "array"? It's a block of memory, represented by its address.
If you want a 2-dimensional array, then you need lots of those blocks -- and you need to know where each of them is located. That means you need an array of addresses, or in other words, an array of int* -- which gives you an int**.
What new int*[n] does is that it allocates memory for an array of addresses, and inside each of them, you go and put the address of an array of ints, allocated via new int[n].

So basically what you have here is an array of pointers to array. In other words, you have an array of pointers in which each pointer in the array points to another array.
here is a picture I found that illustrate this:
The '[]' operator makes you access an element in an array using it index. so A[i] is accessing the i's element in the A array.
A[i] = new int[n];
here you make the i's pointer in an array to point to a new array.
And so what A[i][j]
actually means is that in A[i][j] you are accessing the j's element in the array that the i's element in A points to.

Related

Declaring a 2D array using double pointer

I am confused about this line in a C++ program. The idea of the program is to check whether a 4x4 array is symmetric or not. This part of the code declares a 2D array, which I do not understand.
int** array = new int*[n];
Although, there is another question similar to this but it is about single pointer which I get.
int *array = new int[n];
I do not understand the double pointer. Kindly explain.
How do you create a single pointer array? You do this:
int* myArray = new int[n];
What does this mean? It has two parts. First part is reserving a pointer int* we call it myArray, and the second part is that you reserve n elements, each with size int in memory (this is an array, right?), and you take the address of that array and you save it in the variable myArray.
Now you want a 2D array, which is an array of an array. So Every element of this new array of array is one of these, that we talked about up there. How do we reserve this? We do:
new int*[n];
Because we are reserving n slots, each with type int*, that we talked about before.
Now what is the type of the return value? It's an array of an array, or a "pointer to an array, and the latter is also a pointer to an array", so you write it as
(int*)*
Or
int**
so it becomes
int** array = new int*[n];
int** array is a pointer to a pointer to an int. So by doing this:
int** array = new int*[n];
you are creating a section of memory that holds n int* pointers and pointing array at that memory. For each of these pointers that you have created, it is possible to create a set of ints like so:
for (auto i = 0; i < n; ++i)
array[i] = new int[n];
The resulting memory will look like this:
array -> [ int* | int * | .... n
[int | int | ...][int | int | ...][ ... n
This is however, much much easier if you use some of the std things in c++, ie a std::vector :
std::vector<std::vector<int>> arr(std::vector<int>(0, n), n);
and you are done ...

Double pointer array in c++

I was reading a program about BTree, there I came across this : BTreeNode **C. I understand that it is a 2d array but it was initialized as C=new BTreeNode *[2*t];. I can't understand this: is this a 2d array with dynamic rows and 2t columns ?
Thanks.
You probably well know that double* is a pointer to a double element. In the same way, double** is a pointer to a double* element, which is itself a pointer. Again, double*** is a pointer to a double** element, and so on.
When you instanciate an array to a type T, you usually do new T [size];. For example, for an array of double, you write new double[size];. If your type T is a pointer itself, it's exactly the same : you write new double*[size];, and you get an array of pointers.
In your case, BTreeNode* is a pointer to BTreeNode, and BTreeNode** is a pointer to BTreeNode* which is a pointer to BTreeNode. When you instanciate it by doing new BTreeNode*[size]; you get an array of pointers to BTreeNode elements.
But actually, at this step you don't have a 2D array, because the pointers in your freshly allocated array are NOT allocated. The usual way to do that is the following example :
int num_rows = 10;
int num_cols = 20;
BTreeNode** C = new BTreeNode*[num_rows];
for(int i = 0; i < num_rows; i++)
{
// Then, the type of C[i] is BTreeNode*
// It's a pointer to an element of type BTreeNode
// This pointer not allocated yet, you have now to allocate it
C[i] = new BTreeNode [num_cols];
}
Don't forget to delete your memory after usage. The usual way to do it is the following :
for(int i = 0; i < num_rows; i++)
delete [] C[i];
delete [] C;
The statement C=new BTreeNode *[2*t]; allocates space for 2*t instances of type BTreeNode * and therefore returns a type BTreeNode ** pointing to the first element of such instances. This is the first dimension of your array, however no memory has been allocated for the second dimension.
Yes. If the array is being indexed column-major order (so C[3][4] is the 5th element of the 4th column) then C could, potentially, have ragged (differently sized) columns.
Look for some code that allocates memory for each column, i.e.
C[i] = new BTreeNode[length];
in a loop over i, that would indicate that the 2D array has the same length per column.

C++ Syntax - Multidimensional Dynamic Array

I need help understanding the syntax of multidimensional arrays in C++. In the book I'm learning C++ from, the code snippet looks like this:
typedef int* IntArrayPtr;
IntArrayPtr *m = new IntArrayPtr[num_rows];
for(int i = 0; i < rows; i++){
m[i] = new int[num_columns]
}
My question is this: Why is there a star infront of the m? To me when I see
new IntArrayPtr[num_rows];
that's enough information to tell the compiler that it's an array of pointers that point to int. The star just makes it confusing. Is there something I'm missing here?
Keep in mind that what you have when you do new IntArrayPtr[num_rows] is an array of IntArrayPtrs. In C new[], "allocates size bytes of storage, suitably aligned to represent any object of that size, and returns a non-null pointer to the first byte of this block." So new[] is returning you a pointer to the first element of your array.
For example if num_rows is 3 this is what gets allocated in memory:
m --> [IntArrayPtr]
[IntArrayPtr]
[IntArrayPtr]
m being a pointer is what allows you to use the index operator on it: m[1] returns you the second IntArrayPtr in m.
m is the pointer to pointer which handles starting points of columns as a row. Example of this example in c
int **arr=(int**)malloc(num_rows * (sizeof(int*) ) );
for(i=0;i<row;i++)
{
arr[i]=(int*)malloc(sizeof(int)*col_rows);
}
if we use typedef,
typedef int* IntArrayPtr;
IntArrayPtr *arr=(IntArrayPtr*)malloc(num_rows * (sizeof(IntArrayPtr) ) );
for(i=0;i<row;i++)
{
arr[i]=(IntArrayPtr)malloc(sizeof(int)*col_rows);
}
As you see, firstly we create a pointer array to hold pointers of columns. After that we allocate a place for every columns of array and assign starting points of one dimensional column arrays to one dimensional pointer array.

How to create a pointer to pointers

The problem that I have is to create a specific matrix.
I have to use an array called for example ptr with x pointers. Each pointer in this array should point to a new array (in this case, an int array; each array is a new line in the matrix then).
All x arrays should be created with new; in the end, it should be possible to access the matrix with ptr[a][b] easily.
After a lot of trying and failing, I hope that someone can help me out.
Thank you in advance!
Since this is obviously homework, let me give you a better answer for your sake to go alongside the accepted one.
std::vector<std::vector<int>> matrix(10, std::vector<int>(10));
// ^ ^ ^
// Column count ______| |________________|
// |
// |___ Each column is
// initialized with
// a vector of size 10.
That's a 10x10 matrix. Since we're using vectors, the sizes are dynamic. For statically sized arrays, you can use std::array if you want. Also, here's the reference for std::vector.
If the number of pointers in the array is known, you could simply use a raw array of pointers to int:
int* my_array[10]; // 10 int*
Then you should allocate memory individually for each pointer in the array using usually a for loop:
for(int i=0; i<10; i++){
// each int* in the array will point to an area equivalent to 10 * sizeof(int)
my_array[i] = new int[10];
}
On the other hand, if you don't know the size of the array, then you need a pointer to pointers:
int** ptr_to_ptr = new int*[10];
Note that I am allocating space for 10 int* and not int.
Remember to deallocate the memory allocated above also for the internal pointers, once you don't need that memory anymore.

Can I access elements of a 2D array using pointers in C++?

For 1D array, I can use array name as a pointer and add offset to it to access each element of the array. Is there something similar for 2D arrays?
I defined a 2D array as follows
int arr[2][3] = {{1,2,3}, {4,5,6}};
int** arrPtr = arr;
but I got compiler error for the second line. Shouldn't 2D array have type int**?
I came across another thread here:
C++ Accessing Values at pointer of 2D Array
and saw this:
2dArray = new int*[size];
Could someone please tell me what int*[size] means? (size is an int, I presume).
Thanks a lot.
A multidimensional array defined as yours is is only a single pointer, because the data is encoded in sequence. Therefore, you can do the following:
int arr[2][3]={{1,2,3},{4,5,6}};
int* arrPtr = (int*)arr;
In general, the pointer to the element at arr[a][b] can be accessed by arrPtr + a*bSize + b where bSize is the size of the first array dimension (in this case three).
Your second question relates to dynamic memory allocation - allocating memory at runtime, instead of defining a fixed amount when the program starts. I recommend reviewing dynamic memory allocation on cplusplus.com before working with dynamically allocated 2D arrays.
int* array[10] means an array of 10 pointers to integer.
You can access a 2D array with a simple pointer to its first entry and do some maths exploiting the spacial location principle.
int array[2][2] = {{1,2}, {3, 4}};
int* p = &array[0][0];
for(int i=0; i<2*2; i++)
printf("%d ", *(p++));
If you have a matrix:
1 2
3 4
in memory it is encoded as 1 2 3 4 sequentially ;)