Pointer multidimensional array to multidimensional array - c++

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.

Related

Asterisk after new in 2d array

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

Why does this pointer to pointer two dimensional array assign new int like this

Im struggling to understand something with this code:
int **p_p_tictactoe;
p_p_tictactoe = new int*[ 3 ];
for ( int i = 0; i < 3; i++ )
{
p_p_tictactoe[ i ] = new int[ 3 ];
}
on the line: p_p_tictactoe[i] = new int [3]; The square brackets dereference p_p_tictactoe once so that we are looking at the value at the address stored by p_p_ticatactoe which is another address as it is a pointer to a pointer. Then this address is assigned to a new int but shouldn't this be assigned to the value at the address rather than the address itself like this: *p_p_tictactoe[i] = new int[3]
p_p_tictactoe is an int **.
Therefore, p_p_tictactoe[i] must be an int *.
Therefore, *p_p_tictactoe[i] must be a single, lonely, int.
Assigning the result of new, which would be an int * here, to an int will not have any useful results.
Another helpful way of looking at this: *p_p_tictactoe[i] is equivalent to p_p_tictactoe[i][0]. That, obviously, is an int, a single cell, and stuffing a pointer into it, won't work.
No.
*p_p_tictactoe[i] (also spelt p_p_tictactoe[i][0]) will be one of the ints in the array that you're creating on that line.
As an aside, this is a very inefficient memory layout. Unless your array is likely to change dimensions, or is jagged, prefer a single block of ints with 2D indexing faked on top.

Pointer dimensions when copying an address of multidimensional arra to a pointer

When we have a multidimensional array, and we hope to use a pointer to point to its address. In a book, it says we will do as following.
#include <stdio.h>
int main(){
int a[3][4][5];
int *p[5];
p = a;
return 0;
}
Now, I am quiet confused about the following points:
When I typed the code into CLion, it gives a warning:Incompatible pointer types 'int[5] *' and 'int[3][4][5]', and why is that?
Why does the pointer array *p contains 5 variables instead of 3 variables?
How to use this pointer *p?
Thanks.
1) Because... they are different pointer types! ;) Specifically, a is a three dimensional array of integers, while p is a one dimensional array of pointers to ints. Got that? a contains ints, p contains pointers to ints.
2) Because line int *p[5]; declares it to be 5 long. In C you define how big an array is by the number in the [].
3) Well, if you want p to point to a you would need to make some part of it point to a, as an example p[0] = a;

c++ pointer syntax error

I'm studying for an exam in c++ and i have a question on the past papers
"Write a function in C++ that takes as input an array of doubles and the length of the array, and returns an array twice the length. The first half of the returned array should contain a copy of the contents of the original array. The second half of the returned array should contain the contents of the original array in reverse order."
"The function should have the following prototype: double *copy_and_reverse(double *a, int length);"
since im obviously new to c++ i got stuck in my solution, my code so far is:
double *copy_and_reverse(double *a, int length){
double *b[length*2];
for(int i=0;i<length;i++){
*b[i]=a[i];
}
for(int i=length;i<length*2;i++){
int w=length-1;
*b[i]=a[w];
w--;
}
return *b;
}
int main()
{
double nums[2]={1.23,5.364};
double *pnums=nums;
*pnums=*copy_and_reverse(pnums, 2);
I think i got the core of the method correct but i'm just stuck in the syntax of using pointers, any help is appreciated and if possible a reasoning behind it so i can learn for the exam.
You've got a few problems with this code.
First
double *b[length*2];
Here you're declaring an array of pointers to doubles. The array is of size length * 2, however, none of the pointers in this array are valid yet. This is probably not what you intended to do.
You want an array of doubles, of size length * 2. You can't return an array in C++ but you can return a pointer to some memory that contains an array of doubles.
Let's start by allocating enough memory for all those doubles
double *b= new double[length * 2];
In your first for loop you can treat result as an array
for(int i=0;i<length;i++){
b[i]=a[i];
}
Here you're copying the values from a for each index i to be at the same index. I'll let you figure out how to fill in the reverse part for the second half of the array. You're on the right track, however you might want to think about doing it all in one loop ;)
Your return statement just needs to return your variable b, as it's already a double *.
return b;
An important thing to remember is that you're allocating memory in this function with new. You are responsible for deleting this when you're done with it. Also, when you allocate using new and [] you have to delete using [] as well.
delete [] b;
you can call your function just by de-referencing the first item in your array.
int main() {
double nums[2]={1.23,5.364};
double *pnums = copy_and_reverse(&pnums[0], 2);//don't forget to clean up pnums afterwards!
There are quite many errors in your code. The major one is that you need to allocate new array of doubles. And return that array. I'd suggest compare this with your version line by line:
double *copy_and_reverse(double *a, int length){
double *result = new double[length*2];
for(int i=0;i<length;i++) {
result[i]=a[i];
}
int r = length*2;
for(int i=0; i < length;i++){
result[--r]=a[i];
}
return result;
}
And your main() shall look like:
int main()
{
double nums[2]={1.23,5.364};
double *pnums = copy_and_reverse(nums, 2);
...
delete[] pnums;
}
Ok, there are at least two problems with this:
double *b[length*2];
The first problem is that you are declaring a local array (of pointers), which you will then try to return:
return *b;
(You're returning the wrong thing here, too, but that's another story) You can't return a pointer to a locally-allocated thing because as soon as the function returns, the locally-allocated thing will be destroyed. Instead, given that you must return a pointer to the first element of an array, you have to dynamically allocate that thing using new.
Second, you can't declare an array like this using a length which s only known at runtime. But this problem will be obviated when you use new to dynamically allocate the array.
I would normally say that you shouldn't be doing any of this at all, and just use a std::vector -- but clearly a requirement of this assignment is to use a dynamically allocated C-style array. (Which I take great issue with your professor on.)
I would also say that the prototype:
double *copy_and_reverse(double *a, int length);
doesn't declare a function which takes an array, as your professor incorrectly asserts, but a function which takes a pointer to a double. That that pointer is the first element in an array doesn't magically make a an array. In short: an array and a pointer are not the same thing.
These last two observations are just for your benefit.
I assume this is not your homework and I am trying to help you out.
Look at the comment of code.
double *copy_and_reverse(double *a, int length)
{
double * b = new double[length*2]; //create a new array using new[]
for(int i=0;i<length;i++){
b[i]=a[i]; //addressing element with []
}
int w=length-1; //I assume this is what you want
for(int i=length;i<length*2;i++){
b[i]=a[w];
w--;
}
return b;
}
int main()
{
double nums[2]={1.23,5.364};
double *pnums = copy_and_reverse(nums, 2);
delete[] pnums;
}
Also noted the memory is allocated in the function, so in the main, you want to delete it by using [].

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;