Asterisk after new in 2d array - c++

What is the use of a * after new int in this code? Why can't we write 2d array without * after new int?
int *p1=new int[3];
int *p2=new int[3];
int **pData= new int*[2];

The use of the * after new int is, as you said, for the 2d array.
Without the *, it is simply a 1d array.
There is a similar question which could be useful:
link

new int*[2] says to allocate storage for an array of 2 int*. There's nothing special here: int* is the name of the type being created. The code uses that array of int* to create a 2-dimensional array, but that's in the rest of the code; new int*[2] on its own is simply an array of pointers.
But, yes, you can create a 2-dimensional array directly, without that intervening layer of pointers:
int (*p)[3] = new int[2][3];
This defines p to be a pointer to an array of 3 int. And, because the new expression gives the dimension for that array, you've got a 2-dimensional array. It acts just the way you'd hope for:
p[1][2] = 7;
std::cout << p[1][2] << '\n';

* is a pointer, check this answer out for an explanation of using pointers in C++

Related

Difference between int * array[60] and int * array = new int(60);

int * array[60]; //creates an array of 60 pointers to an int
int * array = new int(60); //same thing?
Do these both result in the same type of array? e.g an array of pointers to integers
I know that the first one uninitialized, and the second one is initialized, but I am unsure of what exactly the second one creates.
int * array = new int(60); //same thing?
No, they're not the same thing. array is just a pointer here, and then point to an int with initialized value 60.
If you meant int * array = new int[60];, array will point to an array of 60 ints, they're still not the same thing.
Note that just as the declaration, int* array means it is a pointer, while int* array[60] means it is an array (of 60 pointers). (Array might decay to pointer, i.e. int** for int* array[60], it's not same as int*.)
Perhaps you do not realize that the second case is not an array, the following program prints 60:
#include <iostream>
int main() {
int* foo = new int(60);
std::cout << *foo << '\n';
return 0;
}
Here are two pictures that illustrate the differences between
int * array[5];
and
int * array = new int(5);
To create a pointer int array use int * array = new int[5];
code,
debug view
One of them creates an array, the other doesn't.
int * array[60]; // Creates an array of 60 integer pointers
To help understand the difference, take into account that the first line creates a 60 pointers-block in memory (in the stack if you are inside main, for example), but the second one only a pointer block.
Both are completely different types. For example, try the following:
array++;
In the first line, it does not work. In the second one, it's ok. If you try:
array[0]++;
In the first line you change the first pointer, in the second one you add 1 to the integer (change to 61).

Array of int pointers

I came across this question:
In the declaration below , p is a pointer to an array of 5 int
pointers.
int *(*p)[5];
which of the following statements can be used to allocate memory for
the first dimension in order to make p an array of 3 arrays of 5
pointers to type int ?
A. p = new int [3][5]*;
B. p = new int (*)[3][5];
C. p = new int [3]*[5];
D. p = new int *[3][5];
E. p = new int (* [3] ) [5];
What is the answer ?
I am not sure I understand the question. Normally I would create a pointer to an array of 5 int as such int* p[5]; I am curious as to why they did it as int *(*p)[5];
Also what does the question want ? Is it asking to initialize (allocate memory) to the first 3 int pointers ? I would appreciate it if someone could explain this to me
F:
using IPA5 = int*[5];
IPA5 * p = new IPA5[3];
Each element p[0], p[1], p[2] is just a plain, typed array of int*. There's nothing dynamic going on beyond the initial dynamic allocation, where 3 is allowed to be a dynamic quantity.
Then p[0][i] for i in [0, 5) is an int *, which you can use in whatever way you like (which includes making it point to the first element of yet anohter dynamic array).
What you would write as:
int* p[5];
is a five element array of pointers to int.
What this declares:
int *(*p)[5];
is a pointer to a five element array of pointers to int, i.e. a pointer to the type of thing you just wrote.
In other words; you could do:
int * a[5];
int * (*p)[5] = &a;
You can mentally read this incrementally as follows:
(*p) // p is a pointer
(*p)[5] // p is a pointer to an array of size 5
int * (*p)[5] // p is a pointer to an array of size 5 of type pointer to int
You need the parentheses around *p, because otherwise:
int ** p[5];
would declare a 5 element array of type int **, or pointer to pointer to int, which is a different thing entirely.
The question is basically asking you to dynamically allocate memory equivalent to three of what a is above, so answer "D" is the correct one.
The answer is
D. p = new int *[3][5];
all the others are syntactically wrong
to realize the difference between
int * p [5];
int * (*p) [5];
consider this example
int *(*p)[5];
int pp[5];
pp[0][0] = new int [5]; //LHS is int , RHS is int ,, compilation error
p[0][0] = new int [5]; //this works because p[0][0] is a pointer not an int
try thinking about each dimension as adding you additional *
back to the question
int *(*p)[5] is giving you 3 * (***p)
so you can assign
p = int *[3][5]
because it has 3 * as well
int* p[5] has type array of size 5 of int*. It decays to int**, so p + 1 will point to the second element of that array.
int *(*p)[5] has type pointer to array of size 5 of int*. You can think of it as decayed two-dimensional array int* [][5]. So p + 1 will point to the second element of the first dimension of that array, that is to the next byte after 5 pointers to int.
Which leads us to the conclusion that the right answer is D.
(This is not to mention that other answers just don't compile regardless of type of p)
What is the answer ?
D
Normally I would create a pointer to an array of 5 int as such int* p[5]; I am curious as to why they did it as int *(*p)[5];
It is not "normally" because int* p[5] is not a pointer to an array of 5 int, it is an array of 5 pointers to int.
Also what does the question want ? Is it asking to initialize (allocate memory) to the first 3 int pointers ?
It's not clear. There is no way "to make p an array of 3 arrays of 5 pointers to type int", to begin with.

Cannot convert char(*)[50] to char* in assignment

Newbie question here...why does the following code only work with a 1D array but not a 2D array? Shouldn't it not make a difference whether b is pointing to the start of a 1D array or a 2D array, as long as it's a char* pointer (as it is)? I thought that the general notation [bound1][bound2] was an equivalent of [bound1*bound2], even over the assignment operation. Help?
main() //this works fine
{
char *b;
b = new char[50];
return 0;
}
.
main() //but this raises the error "Cannot convert char(*)[50] to char* in assignment"
{
char *b;
b = new char[50][50];
return 0;
}
char[50]; is array of 50 elements of type char. Each element has type char. So new char[50]; returns a pointer to first element: char * - pointer to char.
char[50][50] is NOT array of char. It is array of arrays. Each element has type char[50]. So new char[50][50]; returns a pointer to first element: char (*)[50] - pointer to char[50].
Declare b this way:
char (*b)[50];
Test: http://ideone.com/1zJs1O
If your were right with that [bound1][bound2] and [bound1*bound2] were equivalent you wouldn't have created a 2D array. The size of allocated memory, that's what your multiplication implies, is not the problem here, it's about different data types: A 1D array is simply not a 2D array and that's what the compiler is telling you. You should read about C++ type system and type safety.
What is type safety and what are the "type safe" alternatives?

Pointer multidimensional array to multidimensional array

In C++, is there a way to convert a float** to a float[][] type? I also would like to know how to convert it the other way around too.
you can look here to see some more examples, but basically as M M said, you don't need to convert and you can always do:
int x[10];
int *y = x;
same with 2 dimensional arrays
You don't need to convert anything. Just dereference it by [][]:
float **a;
// allocate memory //
a[0][0] = 1;
Be careful to don't touch out-of-bound items which didn't allocate.

int ** vs int [ROWS][COLS] [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
casting char[][] to char** causes segfault?
I have a 2D array declared like this:
int arr[2][2]={ {1,2},{3,4}};
Now if I do:
int ** ptr=(int**) arr;
and:
cout<<**ptr;
I am getting a segmentation fault (using g++-4.0).
Why so? Shouldn't it be printing the value 1 (equal to arr[0][0])?
You can't cast a linear array to a pointer-to-pointer type, since int** doesn't hold the same data int[][] does.
The first holds pointers-to-pointers-to-ints. The second holds a sequence of ints, in linear memory.
You are attempting to assign a double pointer variable to an array... this has been covered exhaustively, see here for information on this. Furthermore, since you declared
int arr[2][2] = ...;
and then try to assign arr to a double pointer
int ** ptr = ... ;
which is guaranteed to not work, hence a segmentation fault. Furthermore, that statement int ** ptr=(int**) arr; is actually cast ing one type (i.e. [][]) to another type (i.e. **) despite they are of type 'int'. They are both different and the compiler will interpret that very differently...
You could do it this way:
int *ptr = &arr;
Now *(ptr + 1) will refer to the 0'th row, *(ptr + 2) will refer to the 1'st row and so on. The only onus on you is to not overstep the markers of where arr is used otherwise an overflow can happen or even a segmentation fault...
What you do now means creating of arrays of pointers where every pointer was explicitly casted. Therefore, you would have an array of pointers like (0x00001, 0x00002, 0x00003 and 0x00004).
When dereferenced, this pointers cause your segfault.
No, int ** is a pointer to a pointer to an int, but a 2-D array is an array of arrays, and &(arr[0][0]) is a pointer to an int.
I believe you should be doing this:
int *ptr = arr;
cout<<*ptr;
or this:
int *ptr = &arr[0][0];
cout<<*ptr;
Try
int *ptr = arr;
More Explanation:
You should assign an adress to the pointer, so it can be derefenced(i mean * operator). What you do is, pointing ptr to memory cell that has the adress a[0][0]. Therefore, you get a segmentation fault.
int arr[2][2] is not an array of arrays - it is a single 2d array. In memory, it is indistinguishable from int arr[4]
What you really want is
int (*ptr)[2] = arr;