I am trying to pass a multidimensional array to a function. When I try to compile I an getting an error saying
[Error] cannot convert 'int (*)[3]' to 'int (*)[2]' for argument '1' to 'void reve(int (*)[2], int)'
What is the problem ? What am I doing wrong? Following is the code I wrote.
#include <iostream>
using namespace std;
const int rows=2;
const int cols=2;
const int n = 3;
void reve(int arr[rows][cols],int n){
int br[3][3],i,j,k,l;
for(i=n-1,k=0;i>=0,k<n;i--,k++){
cout<<endl;
for(j=n-1,l=0;j>=0,l<n;j--,l++)
br[k][l]=arr[i][j];
}
for(i=0;i<n;i++){
for(j=0;j<n;j++)
arr[i][j]=br[i][j];
}
}
int main() {
int i,j,k,l,ar[3][3],br[3][3];
for(i=0;i<3;i++)
for(j=0;j<3;j++)
cin>>ar[i][j];
int n=3;
reve(ar,n);
for(i=0;i<3;i++){
cout<<endl;
for(j=0;j<3;j++)
cout<<ar[i][j];
}
return 0;
}
When you use a 2-d array in a function call, it decays into a pointer type. However, all dimensions but the first one must match exactly.
If the argument type of a function is int (*arg)[2], then, you can't use a variable that is declared as int var[3][3] to call the function. var decays to a pointer whose type is int (*)[3].
It is confusing at first because it seems to work in case of 1-d arrays.
void foo(int arg[10])
{
}
int var[2];
foo(var); // OK
That's because the compiler ignores the size of the first dimension of the array. The above definition of foo is same as:
void foo(int arg[])
{
}
and
void foo(int* arg)
{
}
However, for a multidimensional array, the size of all but the fist dimension must match exactly. Otherwise, they are different types.
The reve() function expects an array of [2][2] but you're passing a [3][3] array.
The ar array in main() is declared as int ar[3][3] while it should have been int ar[rows][cols]
You have reserved 2 blocks in memory. And in your loop, you are taking it from 2 to 0 that makes it 3. Do the following changes.
const int n= 2;
And it should work for your program.
Related
#include <iostream>
using namespace std;
const int up=18;
int realArray[up]={12,28,75,16,66,6,121,19,195,56,108,221,19,93,104,127,73,22}; //definition of a random array
void shakersort(int formArray[up]);//shakersort declared
void tauschen(int *a,int *b){int zw= *a; *a=*b; *b=zw;}
int main()
{
shakersort(realArray[up]); //here happens the error of the conversion
return 0;
}
void shakersort(int formArray[up]){ //the code
for(int i=0; i<up/2;i++){
for (i=0; i<up-1;i++){
if(formArray[i]>formArray[i+1]){
tauschen(&formArray[i], &formArray[i+1]);
}
}
for (int k=up-1; k>0;i--){
if(formArray[k]>formArray[k-1]){
tauschen(&formArray[k], &formArray[k-1]);
}
}
}
}
Not sure why there is a conversion error. Used the same code at declaration and application so not sure why it's not working.
up is an int with value 18 so in this line
shakersort(realArray[up]);
you are basically writing
shakersort(realArray[18]);
which will index a single value from your array (which also happens to be out of bounds, which would therefore be undefined behavior). Instead just pass the array itself
shakersort(realArray);
though I would encourage you to look into using std::vector instead
void shakersort(std::vector<int>& formArray);
so you don't need a global variable floating around to determine the array size, you can just use formArray.size()
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*.
I was trying to make a function for finding number of elements in an array. For this I approached for following code:
#include<iostream>
#include<stdlib>
int no_of_ele(A[]) //function to return size of array
{
return (sizeof(A)/sizeof(A[0]);
}
void main()
{
system("cls");
int arr[5] = {1,2,3,4,5};
cout<<"Number of elements in array are "<<no_of_ele(arr)<<endl;
system("pause");
}
In this approach I got output as follows:
Then, I did this:
cout<<"Size of array is "<<sizeof(arr)<<endl;
cout<<"Size of data type is "<<sizeof(arr[0]);
Now I got absolutely correct output of size as follows:
Why is it?
There are better ways these days, but the closest is:
#include<iostream>
template<std::size_t N>
int no_of_ele(int (&A)[N]){
return sizeof(A)/sizeof(A[0]); // or just return N
}
int main(int argc, char* argv[]){
int arr[5] = {1,2,3,4,5};
std::cout<<"Number of elements in array are "<<no_of_ele(arr)<<std::endl;
return 0;
}
Greetings to 1998. The question is, does Turbo C++ support templates?
See here for more: Is it possible to overload a function that can tell a fixed array from a pointer?
The array decayed to pointer when passed to your function.
sizeof(int)/sizeof(int)... = 1
Reason for this, the parameters are pushed on stack to the function. The compiler as declared by your function declaration will just send the address of your array.
When passing an array as a parameter
int func(int arr[])
Is just as:
int func(int *arr)
Giving an array as a function argument you can't determine its size using the sizeof.
I know even if i pass an array by typing arrayname as argument (ex: getArrayInput(arrayexample); ), it will copy only the adress value of first element not entire array,still i wonder why these code gives error. I know this not the way how it should implemented but i want to understand this error.
main.cpp|13|error: cannot convert 'int*' to 'int**' for argument '1' to 'void getArrayInput(int**)'|
#include <iostream>
using namespace std;
void getArrayInput(int * []);
int main()
{
cout<<"Enter scores on by one.." << endl;
cout<<"To terminate input enter -1"<<endl;
int listof[10]={};
int *ptScores =listof;
getArrayInput(ptScores);
return 0;
}
void getArrayInput(int * []){
for(int i=0;i<10;i++){
cin>>*(pt+i);
if(*(pt+i))=-1){
break;
}
else{
cout<<"Enter next.."<<endl;
}
}
}
It is because
int *
and
int[]
are both of type
int *
therefore, you are here asking for a
int **.
try replacing
void getArrayInput(int * []) by void getArrayInput(int *)
In C, arrays decay in to pointers. In some cases, they are interchangable.
ptScores is of type int* (pointer to int).
getArrayInput expects an int*[] (array of pointers to int).
int*[] decays in to int** (pointer to pointer to int).
The error says you're giving an int* (ptScores) to something that expects an int** (getArrayInput).
How do you fix this?
Take an int*.
void getArrayInput(int* pt){
for(int i=0;i<10;i++){
cin>>pt[i];
if(pt[i]=-1){
break;
}
else{
cout<<"Enter next.."<<endl;
}
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I use arrays in C++?
How do I pass 2-D array to function in c++ via pointer.
I get following error when I try the code below.
error: cannot convert 'int (*)[10][10]' to 'int **' for argument '1' to 'void fn(int **)'
void fn(int **a)
{
cout<<a[0][0]<<" "<<a[0][1];
}
int main()
{
int A[10][10];
A[0][0]=1;
A[0][1]=2;
fn(&A); //????
}
A 2d array, created the way you did, is contigous in memory. The compiler needs to know the size of each segment, to be able to move the pointer to the next one in your function. Writing fn(int (*a)[3]) or fn(int a[][3]) is equivalent. But let's take an example
char a[3][3];
a[0][0] = 01;
a[0][1] = 02;
a[0][2] = 03;
a[1][0] = 04;
a[1][1] = 05;
a[1][2] = 06;
a[2][0] = 07;
a[2][1] = 08;
a[2][2] = 09;
will become
|01|02|03|04|05|06|07|08|09|
in memory.
So if you pass a to a function, it needs to know that it has to increase the a ptr by 3 * sizeof(a) to access a[1][0].
In short : the prototype of the function needs to be void fn(int a[][10]) or void fn(int (*a)[10])
According to the link from #R. Martinho Fernandes , the following is valid C++:
int array_of_arrays[6][7];
int (*pointer_to_array)[7] = array_of_arrays;
So the following should also be valid:
void fn (int (*a)[10])
{
cout<<a[0][0]<<" "<<a[0][1];
}
And I believe the following is also valid:
void fn (int a[][10])
{
cout<<a[0][0]<<" "<<a[0][1];
}
You need to declare fn() as
void fn(int (&a)[10][10])
Arrays in C++ can be treated as pointers to the location of the first element of an array. A two dimensional array can be thought of as an array of pointers, and each of the pointers points to another array. While this isn't strictly speaking how arrays are implemented, C supports implicit conversion between arrays and pointers to the first element, and you can think of them as the same. Array[index] is just syntactical sugar for *(Array + index*sizeof(whatever's in the array)). So for your function to work, you can just do:
void fn(int (*a)[10]) {
cout<<a[0][0]<<" "<<a[0][1];
}
int main() {
int A[10][10];
A[0][0]=1;
A[0][1]=2;
fn(A);
}
No need to get the address of the array first, because it's already a pointer. However, because you're using C++, you really should consider using standard containers:
void fn(vector< vector<int> > const&a) {
cout<<a[0][0]<<" "<<a[0][1];
}
int main() {
vector< vector<int> > A( 10, vector<int>(10) );
A[0][0]=1;
A[0][1]=2;
fn(A);
}
C++ needs to know the array size (of one dimension) to perform 2d indexing.
try:
void fn(int a[][10]) {
cout<<a[0][0]<<" "<<a[0][1];
}