Cannot convert int(*)[5] to int* - c++

When i tried to access array elements using pointer I got this error i don't understand how can i access with the help of pointer.
Error: cannot convert ‘int (*)[5]’ to ‘int*’ for argument ‘1’ to ‘void addd(int*, int)
Any guidance on the matter would be greatly appreciated!
#include <iostream>
using namespace std;
void addd(int *ptr,int length)
{
cout<<"The values in the array are: ";
for(int i = 0; i < length; i++) {
cout<< *ptr <<" ";
ptr++;
}
}
int main() {
int arr[5] = {1, 2, 3, 4, 5};
addd(&arr,5);
//int *ptr = &arr[0];
return 0;
}

Your function receives a pointer to int, so you should just pass the address of the first element.
You can do that:
addd(&arr[0],5);
or simply:
addd(arr,5);

You're doing it wrong. &arr means int (*)[5], but you are using int *ptr. So, you've to use like below:
addd(arr, 5); // this is correct
// addd(&arr, 5) // this is wrong
Here, arr is passed as int *

When you pass an array to a function, for example:
addd(arr,5);
then the array is implicitly converted to a pointer to its first element, an int*. Instead of relying on the implicit conversion, you can make it explicit:
addd( &arr[0],5);
// ^- first element
// ^------ address-of first element
However, arrays are not pointers and taking the address of the array yields a pointer to an array:
using pointer_to_array = int (*)[5];
pointer_to_array p = &arr;

arrays and pointers are pretty much inter-related to each other. An array by default points to the address of the first element, that is the element at index 0. So, working with arrays and pointers are pretty much the same thing( not every time ). So, you do not need to pass on the array as
addd(&arr,5);
you should simply do just
addd(arr,5);
Also , i will say,
The statement
addd(&arr[0],5); does the job, but not a good way to proceed.

Related

Segmentary fault with pointer array C++

I get Segmentary fault with this code:
#include <iostream>
using namespace std;
int* arrayCreate(int length){
int *ew[length];
for (int i=0; i<length; i++)
{
*(ew[i])=i;
}
return ew[0];
}
int main(){
int *ptr=arrayCreate(7);
cout << *ptr << endl;
}
And when I tried to change this line
int *ew[length];
into
int *ew = new int[length];
I have error < indirection requires pointer operand ('int' invalid) >
Any one please explain the difference between these two declaration, why I get segmentary fault and how to fix it?
In the first version, you allocate array of pointers on the stack and return an element of that array - which is dead once the function finishes. Accessing this return value means undefined behaviour.
In the second version, you create array of ints (not pointers) on the heap. Thus the syntax error.
What you want is
int* arrayCreate(int length){
int* ew = new int[length];
for (int i=0; i<length; i++)
{
ew[i]=i;
}
return ew;
}
Or better yet, don't use new[], use std::vector, which manages memory for you:
#include <vector>
#include <numeric> //for std::iota
std::vector<int> arrayCreate(int length){
std::vector<int> v (length);
std::iota(v.begin(), v.end(), 0); //you can use your loop as well
return v;
}
int *ew[length];
Problem 1: The size of an array variable must be compile time constant. length is not a compile time constant. Thus, the program is ill-formed.
how to fix it?
If you need an array with dynamic size, you need to allocate dynamically. Simplest solution is to use std::vector.
why I get segmentary fault
Observation: The pointers in ew have indeterminate values. They don't point to any valid object.
*(ew[i])=i;
Problem 2: You indirect through a pointer stored in the array. Since you're indirecting through an invalid pointer, the behaviour of the program is undefined.
Ask yourself: What int object was ew[i] supposed to be pointing to?
how to fix it?
Don't read indeterminate values, and don't indirect through invalid pointers.
int *ew = new int[length];
Here, you create a dynamic array of integers. Array of integers is not an array of pointers. ew is a pointer to an integer. ew is not a pointer to a pointer.
*(ew[i])=i;
Here, you indirect through ew to access ith successor sibling, and then indirect through that sibling. But the first indirection results in an int object and you cannot indirect through an int.
how to fix it?
Don't try to indirect through an int.
Any one please explain the difference between these two declaration
int *ew[length] is an ill-formed and uninitialised array of pointers to int. int* ew is a single pointer to an int, in this case initialised with the address of a first element of a dynamic array of int.
To get memory for your array in C++ you should write:
int *ew = new int[length];
To return the pointer you should write:
return ew;
This means you return pointer to the beginning of array. It should be mentioned that a[i] <=> *(a + i). You can't write *(ew[i]) = i; to assign, but ew[i] = i; will work.
It should also be said that usage of raw pointers is deprecated in modern c++.

I am getting this strange compilation error in C++

I was doing the Coin change problem, I am trying to do it using Dynamic Programming. But I am getting this compilation which I don't quite understand. Someone told me that I have to assign the 'dp' array dynamically, but he was not sure why. PLease explain this concept .
#include<bits/stdc++.h>
using namespace std;
int solve(int *d, int size, int n , int ** dp){
if(n==0)
return 1;
if(n<0)
return 0;
if(size == 0)
return 0;
if(dp[n][size]>-1)
return dp[n][size];
int x = solve(d,size,n-d[0],dp);
int y = solve(d+1, size - 1, n, dp );
dp[n][size] = x+y;
return x+y;
}
int countWaysToMakeChange(int denominations[], int numDenominations, int value){
int dp[value+1][numDenominations+1];
memset(dp, -1, sizeof dp);
return solve(denominations, numDenominations, value, dp );
}
Error :
Compilation Failed
In file included from Runner.cpp:3:0:
Solution.h: In function 'int countWaysToMakeChange(int*, int, int)':
Solution.h:28:60: error: cannot convert 'int (*)[(numDenominations + 1)]' to 'int**' for argument '4' to 'int solve(int*, int, int, int**)'
return solve(denominations, numDenominations, value, dp);
^
Here is my Main file code:
#include<iostream>
using namespace std;
#include "Solution.h"
int main(){
int numDenominations;
cin >> numDenominations;
int* denominations = new int[numDenominations];
for(int i = 0; i < numDenominations; i++){
cin >> denominations[i];
}
int value;
cin >> value;
cout << countWaysToMakeChange(denominations, numDenominations, value);
}
There are two problems in the code.
First, in the function int countWaysToMakeChange(int denominations[], int numDenominations, int value)
int dp[value+1][numDenominations+1];
is illegal. Array bounds must be compile-time constants. Some compilers allow this sort of things as an extension (and it's legal in C), but it is not valid C++.
Second, the type of dp is "array of array of int". It is not a "pointer to pointer to int", and the compiler is complaining that it can't make that conversion when the code tries to pass dp as the fourth argument to solve.
Arrays are confusing. In most contexts, the name of an array decays into a pointer to its first element. That's why you can write code like this:
void f(int*);
void g() {
int array[20];
f(array);
}
Since dp is an array, its name decays into a pointer to its first element. But this is where it's easy to get lost: as I said earlier, the type of dp is "array of array of int"; when its name decays, the resulting type is "pointer to array of int".
If you want to pass dp to solve, solve has to take the same type: "pointer to array of int". But since you don't know the size of that array when you write solve you can't write that type in the argument list.
That's one reason why multi-dimensional arrays are often represented as one-dimensional arrays, with code to convert the two dimensions into one. The offset is x * width + y, or some minor variant on that. When you do that, your two-dimensional array becomes a one-dimensional array, and its name decays into a pointer to its first element, so you can pass it to a function that expects int*.

Array and pointer

I am wondering how come the # number1 code not working
as I am trying to use increment operator to display the next following element in the array.
But the # number2 code works , and it was the same code but in a function
//# number 1 code
using namespace std;
int main(){
int arrays[5]={2,4,6,8,10};
for(int x=0;x<5;x++){
cout<<*arrays<<endl;
arrays++; //error: lvalue required as increment operand
}
}
//# number 2 code
using namespace std;
void display(int *arr,int size){
for(int x=0; x<5;x++){
cout<<*arr<<endl;
arr++; //This time no error!!!
}
}
int main(){
int arrays[5]={2,4,6,8,10};
display(arrays,5);
return 0;
}
That's because you cannot change the address of an array.
In # number 1 code when you do array++, you are actually trying to operate directly on the variable which is storing the base address of the array.
What you can try instead is something like below:
int *p = array;
p++;
Whereas in the case when you are calling a function passing the array's base address # number 2, you are implicitly doing what has been shown in the above code snippet.
This is a common problem for beginners. Arrays are not pointers!. Arrays are implicitly converted to pointers. That is where the confusion lies. Consider this:
int array[] = {1, 2, 3};
std::cout << *array << '\n';
What do you think is happening when we do *array. Does it really make sense to dereference an array? The array is being implicitly converted to a int * and then dereferenced. What about this:
int array[] = {1, 2, 3};
array++;
std::cout << *array << '\n';
This doesn't compile (as you found out for yourself). In this statement array++, the array is not implicitly converted to a pointer.
Arrays are converted to pointers when you pass them to functions that accept pointers. That makes it possible to do this:
int array[3] = {1, 2, 3};
display(array, 3);
An array is a sequence of objects stored on the stack. You access this sequence of objects as a pointer to the first object. Both arrays and pointers can be subscripted. They share many similarities but are fundamentally different.
To make your first example compile, subscript the array with x:
for (int x = 0; x < 5; x++) {
std::cout << arrays[x] << '\n';
}
Use :
int *arr = arrays;
arr++;
in code #1. It will work. This is because you need first to create a pointer to the base of the array which you can increment as in the second code, you have the pointer in the form of the passed argument to the function.

array pointers in c++

How do you access/dereference with arrays in c++??
for example, if I have this code
int num[] = {0,1,2,3};
int *p = &num;
I thought p was point to the first element in num array?
For some reason, I get a compiler error.
I want to use pointers and increments to access and change the value that is pointing,
for example, p gets the address of the first variable in the int array num and if I increment p, I get the address of the second variable in the int array num.
Any tips would be appreciate it.
I thought p was point to the first element in num array?
No. int *p = &num; is wrong, since &num is not a pointer to an int, i.e. int*, but is actually a pointer to an array of ints, i.e. int (*) [4].
To get a pointer to the first element, you can use int *p = num;, or int *p = &num[0]; instead.

Why doesn't this pointer get the value at the array index?

#include <iostream>
using namespace std;
int func(int arg0, int *arg1, int *arg2);
int main() {
int *b;
int z;
int a[10];
z = func(*a[0], &a[z], b+a[4]);
}
The following code above gives me an error "invalid type argument of unary '*' (have 'int')". I know that * when used in a declaration creates a pointer and when used with a variable name it gets the value stored at that pointer. In the function func(), it takes 3 parameters, 1 int and 2 int pointers. I think that the first argument passed into the function is giving me an error but I am not understanding why. Shouldn't *a[0] get the value of the first element in the a array which was declared as an int?
No, the * when used on a pointer dereferences the pointer. But a[0] is already equivalent to:
*(a + 0) // And since the offset is 0, this is equivalent to *a.
In other words, dereferencing a pointer to the beginning of the array that has been offset to give you the value of the item at a given 'index'. What YOU wrote is equivalent to:
**(a + 0) // And since the offset is 0, this is equivalent to **a.
Therefore, you are trying to 'dereference' an int, which won't work. Since * is not a valid unary operator for an int, that fails and causes the error you've seen to appear.
*a[0] is the same as **a.
Given the declaration int a[10];, it should be fairly clear that you are not able to dereference a twice.
If you want the first element of the array a, then that is simply a[0].
You could also simplify your example to this, and still get the same error:
int main() {
int a[10];
int b = *a[0];
}