This question already has answers here:
Passing a 2D array to a C++ function
(18 answers)
Closed 4 years ago.
I know how to pass 1D array pointer to a function by the following code
void fiddleWithArray(int*);
int main(){
int list[10] = {1, 3, 5, 7, 9, 11, 13, 17};
cout << "List at 0 before being passed is... " << list[0][0] << endl;
cout << "List at 1 before being passed is... " << list[1][0] << endl;
fiddleWithArray(list);
cout << "List at 0 after being passed is... " << list[0][0] << endl;
cout << "List at 1 after being passed is... " << list[1][0] << endl;
}
void fiddleWithArray(int* input){
input[0] = 45;
input[1] = 18;
}
However, when I try to do something similar for a 2D array(as shown below) I get an error.
void fiddleWithArray (int** input);
int main ()
{
int list [10][2]={{1,3},{5,7},{9,11},{13,17},{7,4},{5,90},{9,1},{3,25}};
int ** pointer;
pointer=&list;
cout<< "List at 0 before being passed is ... "<< list[0][0]<< endl;
cout<< "List at 1 before being passed is ... "<< list[1][0]<< endl;
fiddleWithArray(pointer);
cout<< "List at 0 after being passed is ... "<< list[0][0]<< endl;
cout<< "List at 1 after being passed is ... "<< list[1][0]<< endl;
}
void fiddleWithArray(int** input)
{
cout << input [6][1]<< endl;
}
The compiler gives an error saying "error: cannot convert ‘int (*)[10][2]’ to ‘int**’ in assignment
pointer=&list;"
I am also open to alternate methods of passing a 2D array pointer to a function.
Keeping your data structure, if you want to pass list to fiddleWithArray you can declare it as
void fiddleWithArray (int input[][2]);
and then, in the main program, call it as
fiddleWithArray(list);
There is also another problem in your program: cout << list[0] does not work. If you want to print the contents of the array when the first index is fixed to 0 you would write something like
cout << list[0][0] << " " << list[0][1]
If you instead intended to write the array where the second index is fixed to 0 or 1, then, to keep things easily, you need a short loop like
for (unsigned int i = 0; i < 10; i++)
cout << list[i][0] << " ";
cout << endl;
Finally, instead of using int[][] you may want to use std::arrayintroduced in C++11.
void fiddleWithArray(int input[10][2])
{
cout << input[6][1] << endl;
}
int main()
{
int list[10][2] = {{1,3},{5,7},{9,11},{13,17},{7,4},{5,90},{9,1},{3,25}};
int (*pointer)[10][2];
pointer=&list;
cout << "List at 0 before being passed is ... "<< list[0][0]<< endl;
cout << "List at 1 before being passed is ... "<< list[1][0]<< endl;
fiddleWithArray(*pointer);
cout << "List at 0 after being passed is ... "<< list[0][0]<< endl;
cout << "List at 1 after being passed is ... "<< list[1][0]<< endl;
}
Will be better using std::array
Related
This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
When a function has a specific-size array parameter, why is it replaced with a pointer?
(3 answers)
Closed 4 years ago.
I'm very new to C++. From examples, I find this use of sizeof in order to retrieve the length of an array
int main()
{
int newdens[10];
// the first line returns 10 which is correct
std::cout << "\nLength of array = " << (sizeof(v1)/sizeof(*v1)) << std::endl;
std::cout << "\nLength of array = " << (sizeof(v1) << std::endl; //returns 40
std::cout << "\nLength of array = " << (sizeof(*v1)) << std::endl; //returns 4
}
But if i wrote a function like this
#include <iostream>
void myCounter(int v1[])
{
int L, L2, L3;
L = (sizeof(v1)/sizeof(*v1));
L2 = (sizeof(v1));
L3 = (sizeof(*v1));
std::cout << "\nLength of array = " << L << std::endl;
std::cout << "\nLength of array = " << L2 << std::endl;
std::cout << "\nLength of array = " << L3 << std::endl;
}
int main()
{
int v1[10];
std::cout << "\nLength of array = " << (sizeof(v1)/sizeof(*v1)) << std::endl;
std::cout << "\nLength of array = " << (sizeof(v1)) << std::endl;
std::cout << "\nLength of array = " << (sizeof(*v1)) << std::endl;
myCounter(v1);
}
the outputs are L=2, L2 = 8, L3 = 4. I can't understand where the problem is.
How to retrieve the correct lenght of v1 inside the function?
Your problem here is that sizeof() is resolved at compile time. As it has no information about how large is your array, it cannot tell its size. It interprets it as a pointer to an int, which is 64-bit on your machine.
The best way for you is to use std::vector instead of C-style array and use its method size().
I have a problem passing a pointer to a function. Here is the code.
#include <iostream>
using namespace std;
int age = 14;
int weight = 66;
int SetAge(int &rAge);
int SetWeight(int *pWeight);
int main()
{
int &rAge = age;
int *pWeight = &weight;
cout << "I am " << rAge << " years old." << endl;
cout << "And I am " << *pWeight << " kg." << endl;
cout << "Next year I will be " << SetAge(rAge) << " years old." << endl;
cout << "And after a big meal I will be " << SetWeight(*pWeight);
cout << " kg." << endl;
return 0;
}
int SetAge(int &rAge)
{
rAge++;
return rAge;
}
int SetWeight(int *pWeight)
{
*pWeight++;
return *pWeight;
}
My compiler outputs this:
|| C:\Users\Ivan\Desktop\Exercise01.cpp: In function 'int main()':
Exercise01.cpp|20 col 65 error| invalid conversion from 'int' to 'int*' [-fpermissive]
|| cout << "And after a big meal I will be " << SetWeight(*pWeight);
|| ^
Exercise01.cpp|9 col 5 error| initializing argument 1 of 'int SetWeight(int*)' [-fpermissive]
|| int SetWeight(int *pWeight);
|| ^
PS: In real life I wouldnt use this but I got into it and I wanna get it working this way.
You shouldn't dereference the pointer. It should be:
cout << "And after a big meal I will be " << SetWeight(pWeight);
Also, in SetWeight(), you are incrementing the pointer instead of incrementing the value, it should be:
int SetWeight(int *pWeight)
{
(*pWeight)++;
return *pWeight;
}
int *pWeight = &weight;
This declares pWeight as a pointer to an int. SetWeight actually takes a pointer to an int, so you can just pass pWeight straight in without any other qualifiers:
cout << "And after a big meal I will be " << SetWeight(pWeight);
First I took your feedback and changed:
cout << "And after a big meal I will be " << SetWeight(*pWeight);
// to
cout << "And after a big meal I will be " << SetWeight(pWeight);
// But after that I changed also:
*pWeight++;
// to
*pWeight += 1;
The * symbol can have two different meanings in C++. When used in a function header, they indicate that the variable being passed is a pointer. When used elsewhere in front of a pointer it indicates that to which the pointer is pointing. It seems you may have confused these.
This question already has answers here:
Pointer errors in the method of transmission(c++)
(4 answers)
Closed 8 years ago.
Question: I can't seem to set a pointer to an address that was created inside of a function. It always gets set to Null, how do I fix this?
Problem: I believe the problem is caused by the variable being created inside of another function. What's happening is that after the function executes, the pointer is set to NULL again.
Code:
void listAdd(int *list, int &length) {
int* tempList = new int[ length + 1 ];
for( int i = 0; i < length; i ++ )
{
(tempList)[ i ] = (list)[ i ];
}
cout << " Previous adress: " << hex << list << endl;
if ( list != NULL )
delete[] list;
list = new int[ length + 1 ];
cout << " New address: " << hex << list << endl << dec;
for( int i = 0; i < length; i ++ )
{
(list)[ i ] = (tempList)[ i ];
}
delete[] tempList;
cout << " Enter a number: ";
int stored = 0;
cin >> stored;
(list)[length -1] = stored;
length ++;
cout << " Length: " << length << "\n";
cout << " value at array point 0: " << (list)[length -1];
cout << "\n retry " << (list)[length-1] <<"\n";
cout << "\n \n \n This is pointing to 0x" << hex << list << '\n' << flush;
}
It seems you would like the changes to list to be valid after the function returned: since list is passed by value, the object manipulated inside the function happens to be a copy of the one you passed in. You probably either want to pass the object by reference, i.e.:
void listAdd(int*& list, int &length) {
// ...
}
... or return the result
int* listAdd(int* list, int& length) {
// ...
return list;
}
list = listAdd(list, length);
Well, realistically, you really really want to encapsulate the objects in a class or just use std::vector<int>.
I need to do the following:
Assume that the C++ array
int fib[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21 };
is stored on a 32-bit machine, at memory address 0xA0000000 (hexadecimal). What are the values of the following expressions?
fib
*fib
&fib[0]
&fib[6]
*(fib+7)
I tried writing this code to try and print out the desired values.
int main()
{
int i = 0;
int *p = &A0000000;
cout << "i= " << i << endl;
cout << "p= " << p << endl;
*p = 0;
cout << "i=" << i << endl;
int &r = i;
r = 0;
cout << "i= " << i << endl;
int fib[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21 };
cout << "fib= " << fib << endl;
cout << "*(*fib)= " << *fib << endl;
cout << "&fib[0]= " << &fib[0] << endl;
cout << "*(fib+7)= " << *(fib+7) << endl;
cout << "&fib[6]= " << &fib[6] << endl;
system("PAUSE");
return 0;
}
I get the following error message:
c:\users\inquirer\documents\visual studio 2010\projects\fib1\fib1\fib1.cpp(7): error C2065: 'A0000000' : undeclared identifier
Thank you in advance for the help. What do I need to do to print out the correct values?
To fix the compilation error try
int* p=(int*)0xA0000000;
Whatever this should be good for ...
You cannot store something at an arbitrary virtual memory address.
*p = 0; will crash at runtime, because 0xa0000000 is probably not a valid location to write to.
Try int *p = new int and print the address you got. It will be less beautiful than 0xa0000000 but it will be sufficient to visuallise your experiment.
This is my first shot at brute-forcing the NP-complete knapsack problem. In this form you have a list of items which must be thrown off a plane each with a weight and cost. The goal is to throw out some remain_weight while minimizing cost.
Each recursion level(y direction if graphed) is a new remain_weight after items have been selected. A for loop searches through all the items(x direction if graphed)
Test Case 1 - Works
Item / Weight / Cost
0 100 101
1 300 297
What is the best way to put these two functions in a class.
enum item_type {weight, cost};
int algo(int &cost_low, int &cost_high, int throw_weight, int item_id, int item_matrix[][2])
{
int quantity,remainder;
quantity=throw_weight/item_matrix[item_id][weight];
remainder=throw_weight%item_matrix[item_id][weight];
if(remainder==0)
{
cost_low=(quantity-1)*item_matrix[item_id][cost];
cost_high=quantity*item_matrix[item_id][cost];
throw_weight-=(quantity-1)*item_matrix[item_id][weight];
}
else
{
cost_low=(quantity)*item_matrix[item_id][cost];
cost_high=(quantity+1)*item_matrix[item_id][cost];
throw_weight-=(quantity)*item_matrix[item_id][weight];
}
return throw_weight;
}
int branch(int remain_weight)
{
static int depth_level = 0;
static int cost_present=32000;
int remain_weight_next;
int cost_low, cost_high, cost_branch;
depth_level++;
cout << "Entering at depth: " << depth_level << " :remain_weight: " << remain_weight << endl ;
int item_id, item_count=2;
int item_matrix[][2] =
{
{100, 101},
{300, 297},
// {400, 401},
// {800, 800},
// {1200, 1200},
// {1999, 1800},
// {2000, 2000},
};
for(item_id=0; item_id<item_count; ++item_id)
{
cout << "--For loop id is: " << item_id << endl;
if(item_matrix[item_id][weight]<remain_weight)
{
cout << "----item_weight: " << item_matrix[item_id][weight] << " : is less than remain_weight : " << remain_weight << endl;
remain_weight_next=algo(cost_low,cost_high,remain_weight,item_id,item_matrix);
cost_branch = branch(remain_weight_next);
cost_present=cost_low + cost_branch;
if(cost_present>cost_high)
cost_present=cost_high;
cout << "--**remain_weight: " << remain_weight << endl;
cout << "--**cost_low: " << cost_low << endl;
cout << "--**cost_high: " << cost_high << endl;
cout << "--**cost_branch: " << cost_branch << endl;
}
else
{
cout << "----item_weight: " << item_matrix[item_id][weight] << " : is greater than remain_weight : " << remain_weight << endl;
if(cost_present>item_matrix[item_id][cost])
cost_present=item_matrix[item_id][cost];
}
cout << "--**cost_present: " << cost_present << endl;
}
cout << "Leaving at Depth: " << depth_level << endl;
depth_level--;
return cost_present;
}
int &cost_low, int &cost_high is a tip-off. If a function is called repeatedly, and on each iteration modifies the same objects, then that function and those objects should probably be members of the same class.
If you look further, you see that algo also works on cost_matrix[] and weight_matrix[] (No, it's not a 2D array). These could also become members.
branch is a bit complex because you 're mixing up things. It's recursive, but you also initialize item_matrix in each and every recursion. No problem once you've moved item_matrix into a class; the ctor will then initialize it. But do allocate that class outside branch() for the same recursive reasons.
Finally, be a bit more compact. Don't define objects early; define them when you have a value. Dare to write cout << "Entering at depth: " << ++depth_level;