Declaring a 2D array using double pointer - c++

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

Related

What are the different ways of declaring a 2D array in C++?

There is one where you just write array[rowSize][colSize]. Another where you declare it as an array of pointers to arrays using new. (From How do I declare a 2d array in C++ using new? )
int** ary = new int*[rowCount];
for(int i = 0; i < rowCount; ++i)
ary[i] = new int[colCount];
There should be one using malloc. Are there any more? What are the pros/cons of each of them? How about their speed of execution/processing?
(This is an interview question. So, more than just suggesting the most optimal method, I need to know what each of these methods do)
I do not fully understand the question here, but I can tell you the differences between the two. When using new (or malloc) the variables stay off the stack. When declaring the variable like:
int iarray[10][10];
it uses stack space. The downside to using the new operator is that you must remember to use the delete [] operator, too.
There are different types:
1. This is an array where each element is an array itself:
int array[rowSize][colSize];
It is like this:
typedef int A[colSize];
A array[rowSize];
where sizeof(A) is colSize*sizeof(int)
and sizeof(array) is rowSize*sizeof(A)
indexes of elements in memory for a[3][3]:
|0,0|0,1|0,2|1,0|1,1|1,2|2,0|2,1|2,2|
2. This instead is a pointer to a pointer:
int** ary
where ary may refer to array of pointers
where each element may refer to any size array of int.
size of pointer is machine dependent.
It initialized in example as array of poiner. And after that each element of it is initialized newely created array.
For your example:
int** ary = new int*[rowCount];
for(int i = 0; i < rowCount; ++i)
ary[i] = new int[colCount];
have rowCount and colCount equal to 3 and 3,
than allocated arrays and indexes in memory:
|0|1|2| ... |0,0|0,1|0,2| ... |1,0|1,1|1,2| ... |2,0|2,1|2,2|
| | | ^ ^ ^
| | -------- | |
| ---------------------------- |
------------------------------------------------

What value does a pointer to pointer get assigned when points to a dynamically allocated memory?

Consider the following case:
int **my_array = new int*[10];
What do we assign to my_array here?
my_array is a pointer that points to what?
Is there any way to iterate through my_array (the pointer) and set up a two-dimensional array of integers (and not int*)?
We assign to my_array the address of an array. The array contains pointers which can point to other arrays, but don't yet.
Yes, we can do this:
int **my_array = new int*[10];
for(int i=0; i<10; ++i)
my_array[i] = new int[13];
my_array[2][11] = 500;
What do we assign to my_array here?
You can assign an int* to the elements of my_array. E.g.
my_array[0] = new int[20];
or
int i;
my_array[0] = &i;
my_array is a pointer that points to what?
It points to an an array of 10 int* objects.
Is there any way to iterate through my_array (the pointer) and set up a two-dimensional array of integers (and not int*)?
Not sure what you are expecting to see here. An element of my_array can only be an int*.
If you want my_array to be a pointer to a 2D array, you may use:
int (*my_array)[20] = new int[10][20];
Now you can use my_array[0][0] through my_array[9][19].
PS If this is your attempt to understand pointers and arrays, it's all good. If you are trying to deploy this code in a working program, don't use raw arrays any more. Use std::vector or std::array.
For a 1D array, use:
// A 1D array with 10 elements.
std::vector<int> arr1(10);
For a 2D array, use:
// A 2D array with 10x20 elements.
std::vector<std::vector<int>> arr2(10, std::vector<int>(20));

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.

initialize an int[][] with new()

I am a c++ newbie. While learning I came across this.
if I have a pointer like this
int (*a)[2][3]
cdecl.org describe this as declare a as pointer to array 2 of array 3 of int:
When I try
int x[2][3];
a = &x;
this works.
My question is how I can initialize a when using with new() say something like
a = new int [] [];
I tried some combinations but doesn't get it quite right.
Any help will be appreciated.
You will have to do it in two steps - first allocate an array of pointers to pointers(dynamically allocated arrays) and then, allocate each of them in turn. Overall I believe a better option is simply to use std::vector - that is the preferred C++ way of doing this kind of things.
Still here is an example on how to achieve what you want:
int a**;
a = new int*[2];
for (int i =0; i< 2;++i){
a[i] = new int[3]
}
... use them ...
// Don't forget to free the memory!
for (int i = 0; i< 2; ++i) {
delete [] a[i];
}
delete [] a;
EDIT: and as requested by Default - the vector version:
std::vector<std::vector<int> > a(2, std::vector<int>(3,0));
// Use a and C++ will take care to free the memory.
It's probably not the answer you're looking for, but what you
need is a new expression whose return type is (*)[2][3] This
is fairly simple to do; that's the return type of new int
[n][2][3], for example. Do this, and a will point to the
first element of an array of [2] of array of [3] int. A three
dimensional array, in sum.
The problem is that new doesn't return a pointer to the top
level array type; it returns a pointer to the first element of
the array. So if you do new int[2][3], the expression
allocates an array of 2 array of 3 int, but it returns
a pointer to an array of 3 int (int (*a)[3]), because in C++,
arrays are broken (for reasons of C compatibility). And there's
no way of forcing it to do otherwise. So if you want it to
return a pointer to a two dimensional array, you have to
allocate a three dimensional array. (The first dimension can be
1, so new [1][2][3] would do the trick, and effectively only
allocate a single [2][3].)
A better solution might be to wrap the array in a struct:
struct Array
{
int data[2][3];
};
You can then use new Array, and everything works as expected.
Except that the syntax needed to access the array will be
different.