Double pointer array in c++ - 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.

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 ...

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 does a pointer to a pointer correspond to a 2D array?

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.

dynamic allocation of rows of 2D array in c++

In c++, I can create a 2D array with fixed number of columns, say 5, as follows:
char (*c)[5];
then I can allocate memory for rows as follows
c = new char[n][5];
where n can be any variable which can be assigned value even at run time. I would like to know whether and how can I dynamically allocate variable amount of memory to each row with this method. i.e. I want to use first statement as such but can modify the second statement.
Instead of a pointer to an array, you'd make a pointer to a pointer, to be filled with an array of pointers, each element of which is in turn to be filled with an array of chars:
char ** c = new char*[n]; // array of pointers, c points to first element
for (unsigned int i = 0; i != n; ++i)
c[i] = new char[get_size_of_array(i)]; // array of chars, c[i] points to 1st element
A somewhat more C++ data structure would be a std::vector<std::string>.
As you noticed in the comment, dynamic arrays allocated with new[] cannot be resized, since there is no analogue of realloc in C++ (it doesn't make sense with the object model, if you think about it). Therefore, you should always prefer a proper container over any manual attempt at dynamic lifetime management.
In summary: Don't use new. Ever. Use appropriate dynamic containers.
You need to declare c as follows: char** c; then, allocate the major array as follows: c = new char*[n]; and then, allocate each minor array as follows: c[i] = new char[m]
#include <iostream>
using namespace std;
main()
{
int row,col,i,j;
cout<<"Enter row and col\n";
cin>>row>>col;
int *a,(*p)[col]=new (int[row][col]);
for(i=0;i<row;i++)
for(j=0;j<col;j++)
p[i][j]=i+j;
for(i=0;i<row;i++)
for(j=0;j<col;j++)
cout<<i<<" "<<j<<" "<<p[i][j]<<endl;
//printf("%d %d %d\n",i,j,p[i][j]);
}

What is ** in C++

I am currently reading some C++ source code, and I came across this:
double **out;
// ... lots of code here
// allocate memory for out
out = new double*[num];
Not entirely sure what it does, or what it means. Is it a pointer... to another pointer?
There is also the following:
double ***weight;
// allocate memory for weight
weight = new double**[numl];
I am quite confused :P, any help is appreciated.
new double*[num] is an array of double pointers i.e. each element of the array is a double*. You can allocate memory for each element using out[i] = new double; Similarly weight is an array of double**. You can allocate the memory for each weight element using new double*[num] (if it is supposed to be an array of double*)
It's a pointer to pointer to double. Or array of pointers to double. Or if every pointer itself allocates array it might be a matrix.
out = new double*[num]; // array of pointers
Now it depents if out[0] is allocated like this:
out[0] = new double; // one double
or like this:
out[0] = new double[num]; // now you've got a matrix
Actually, writing
double*[] out;
is in C/C++ equal to
double** out;
and it means an array of pointers to double. Or a pointer to pointers of double. Because an array is nothing more than just a pointer. So this is in essence a two-dimensional array.
You could as well write
double[][] out;
And likewise, adding another pointer level, will add another dimension to your array.
So
double ***weight;
is actually a pointer to a three-dimensional array.
Basically both of your code fragments allocate array of pointers. For allocation it does not matters to what. Correct declaration is needed only for type checks. Square bracjets should be read separately and means only it is array.
Consider following code as quick example:
#include <stdio.h>
int main()
{
unsigned num = 10;
double **p1, ***p2;
p1 = new double*[num];
p2 = new double**[num];
printf("%d\n", sizeof(p1));
printf("%d\n", sizeof(p2));
delete [] p1;
delete [] p2;
return 0;
}
Yes, both are just pointers. And memory allocated is sizeof(double*) * num.