In the following call-by-value example, I cannot understand why this code is not changing the value of the 5 to a 6.
Line 11 calls the function changeValue which has the value 6, so I would have thought 6 should be output, however 5 is still output?
#include <iostream>
using namespace std;
void changeValue(int value);
int main()
{
int value = 5;
changeValue(value);
cout << "The value is : " << value << "." << endl;
return 0;
}
void changeValue(int value)
{
value = 6;
}
// This doesn't change the value from 5 to 6. 5 is output?
When you pass a function argument by value a copy of the object gets passed to the function and not the original object.Unless you specify explicitly arguments to functions are always passed by value in C/C++.
Your function:
void changeValue(int value)
receives the argument by value, in short a copy of value in main() is created and passed to the function, the function operates on that value and not the value in main().
If you want to modify the original then you need to use pass by reference.
void changeValue(int &value)
Now a reference(alias) to the original value is passed to the function and function operates on it, thus reflecting back the changes in main().
The value of value isn't changing because your int that you pass to the function is being copied into the stack frame of the function, then it's being changed, and when the function exits the copy is destroyed. The original in main's stackframe has not changed, since it was copied to the changeValue.
If you want to change it, you should pass a reference to an int, like so void changeValue(int& value), which says that the value isn't copied into the function, but merely an alias to the original is passed.
The behavior being observed currently is because passing by value means a copy of value (new integer with value of value) is actually passed to the function.
You have to pass by reference. For that the changeValue function will look like this:
void changeValue(int& value)
Rest of the code will remain the same.
Passing a variable by reference means the same int value declared in main is passed to the changeValue function.
Alternatively, you can pass a pointer to value to the changeValue function. That will however, require changes to how you call the function also.
int main()
{
int value = 5;
changeValue(&value);
...
return 0;
}
void changeValue(int* value)
{
*value = 6;
}
I'm including this answer as another way to think about writing functions and passing parameters by value.
You could also have written this code in the following way. That is pass the parameter by value, modify the local copy in the function, which does not alter the original value, and return the altered value.
int changeValue(int val)
{
val = 6;
return val;
}
int main()
{
int value = 5;
value = changeValue(value);
cout << "The value is : " << value << "." << endl;
return 0;
}
I am not in any way indicating my suggestion for your program is better than passing by reference. Instead, it is just the way learning a functional programming language (Clojure) is affecting the way I think.
Also, in languages like Python, you cannot modify a scalar parameter. You can only return a new value. So my answer is more of an exercise in thinking about things differently in C/C++.
AND:
the copy is assigned 6, but the change is not returned.
you need some reference or pointer if you want to change the value:
try using a method signature like:
void changeValue(int& value)
that will probably do what you expected
This is because the change in the changeValue () function is local. When you can changeValue (value) the contents of the variable value in main is copied in the formal argument named value (same name) of the function. Same name does not mean that the both are same. The value you are accessing inside the function is a copy of the value you had in the main.
To change you either need to pass it by reference or a pointer
void changeValue (int *val)
{
*val = 6;
}
call with changeValue (&value) in main
This works because the address of the variable value in main is passed and this address value is copied into val of the function. By doing *val we can get the contents of the address which was copied into val, which in actually the contents of value in main.
OR
void changeValue (int &val)
{
val = 6;
}
Related
I'm trying to make a function that reduces a certain integer value by 30.
#include <iostream>
using namespace std;
int valuered(int value)
{
value-=30;
}
int main()
{
int number{100};
valuered(number);
cout<<number;
return 0;
}
You are passing value by value, meaning the valuered function has a local copy of the argument. If you want to affect the outside variable number the function should look like this:
void valuered(int& value)
{
value-=30;
}
Here value is being passed by reference, meaning any changes done to it inside the function will propagate to the actual argument that has been passed in.
Also note that I have changed the return type from int to void, since you are not returning anything. Not returning anything from a function declared to return a value makes the program have undefined behavior.
pass by reference is important to use the modified value out side the function because if you are using pass by value then the change in value will only exist inside the user defined function.
#include<iostream>
using namespace std;
int valuered(int &v) // pass by reference is needed to use the modified value in main function.
{
v-=30;
return v;
}
int main()
{
int number=100;
valuered(number);
cout<<number;
}
This question already has answers here:
Pass by reference and value in C++
(5 answers)
Closed 5 years ago.
I wrote the folloing code to test how to change values of class object in a function.
using namespace std;
class test{
public:
int a;
};
void runer(test testXX){
testXX.a=10;
}
int main()
{
test test1;
test1.a=5;
runer(test1);
cout<<test1.a;
return 0;
}
When I run the following code the output is 5 and not 10. Is it because I can't change the values of class instances, like I can't change the values of array members without using pointers? I would be grateful if someone could clarify that!
void runer(test testXX){
testXX.a=10;
}
Takes a full copy of the type test, so it is modified in the function, but a different instance to the one in main.
Parameters in C++ are sent by value. The simplest example which makes sense is
int function( int value ) {
for( ; value > 0 ; value-- ){
cout << "Hello\n";
}
}
int main( int , char ** ){
int value = 10;
function( value ); // display 10 things
function( value ); // display 10 things again (not modified).
function( 5 ); // also not making sense, if parameter is modified.
}
To allow objects to be modified, they need to be sent as references, or pointers. This allows the value of the item to be changed. The literal 5 can not be sent to a function expecting a reference.
void runer(test & testXX){
testXX.a=10;
}
Now the same object is sent from main to runner, and modifications are done to the single object.
You are passing the argument to the function by value, so it gets a local copy that only lives as long as the scope of the function.
If you want the function to be able to modify the original object that you pass in, then pass it by non-const reference void runer(test& testXX) .
Your code makes a call by value. Hence, the change doesn't appear in the actual object. To change the value of the attribute of the object you need to make a call by reference.
void runer(test &t){
t.a = 10;
}
I have an int member named size within my blob class whose value I am attempting to change within a method. Initially, I tried...
void blob::make_union(blob parent_blob){
parent=&parent_blob;
parent_blob.size = parent_size
}
Then I tried making a function whose sole purpose was to change the size value. Its worth noting that it changes the values within the function as verified by some cout statements.
int blob::change_size(int dat_size){
size=size+dat_size;
return this.size;
}
after making the new method change my other method
'void blob::make_union(blob parent_blob){
parent=&parent_blob;
int temp = size;
parent_blob.size = parent_blob.change_size(temp);
}'
still no dice. The following within main function does work.
if (charmatrix[m-1][n-1]==charmatrix[m][n]){
blobmatrix[m][n].make_union(blobmatrix[m-1][n-1]);
blobmatrix[m-1][n-1].size=blobmatrix[m-1][n-1].size + blobmatrix[m][n].size;
What am I doing wrong?
You are passing your blob class by value: you are making a copy of your blob object, and that is what the function change_size is working with.
void increment_number(int i) { ++i; }
void increment_number_ref(int& i) { ++i; }
int main()
{
int n = 6;
// This takes a copy of the number, and increments that number, not the one passed in!
increment_number(n);
// n == 6
// This passed our object by reference. No copy is made, so the function works with the correct object.
increment_number_ref(n);
// n == 7
return 0;
}
You need to pass your blob by reference (or as a pointer) if you wish to modify that object's value: see above.
In languages that have pass by reference and pass by value - if you have a situation where you make a change, and then suddenly the change is 'gone', you're almost certainly passing a copy vs a reference.
Try changing the prototype to pass in the blob by reference.
The answer is probably stupidly easy, but I have stared at this code for quiet a while now and I simply can't find the solution.
Here is my problem. I have a pointer to a base class. Then I call a function to find an element in a vector of objects derived from that class. The pointer is passed as a parameter and filled with the found object. If I try to read a member variable of what the pointer points to I get a SIGSEV.
This is the code:
Base* control;
if(findControlByName("aName", control)) {
std::cout << control->name << std::endl; // SIGSEV happens here
}
//...
bool findControlByName(std::string name, Base* control) {
for(size_t i = 0; i < controls.size(); i++) {
if(controls[i]->name == name) {
control = controls[i];
std::cout << control->name; // this works
return true;
}
}
return false;
}
How do I do this properly?
To elaborate on my above comment, when you assign a value to a pointer parameter in a function, that value is local to the scope of the function, just like any other parameter that is passed by value. Assigning a value to the parameter in the scope of the function does not change it outside the scope of that function unless it is passed by reference.
An example:
void someFunc(int * x)
{
static int my_static = 5;
x = &my_static;
}
void someFunc2(int * &x)
{
static int my_static_2 = 7;
x = &my_static_2;
}
//somewhere else:
int * ptr;
someFunc(ptr);
//ptr is unchanged/still uninitialized
someFunc2(ptr);
//ptr points to my_static_2
If the signature of someFunc is changed to take a reference parameter, the parameter will be passed by reference instead of passed by value.
I am getting access violation error in the below code..i have pointed it out in the program.
void *pBuff = 0;
void set_data(void *pBuff)
{
int value = 70, i;
int *phy_bn = new int[8];
for(i=0; i<8; i++)phy_bn[i] = value;
pBuff =phy_bn;
cout<<((int*)pBuff)[0];//..accessing 0th element value..no error here..gives 70 as result..
}
int main()
{
set_data(pBuff);
cout<<((int*)pBuff)[0];//acces violation error
return 0;
}
Why that access violation even when i am not assigning it the address of a local variable...
Yes i can use vector or pass by reference.
But i want to know why pBuff is not getting assigned
Because it is a copy of the pointer being modified within set_data(). Pass the pointer by reference so the change is visible to the caller:
void set_data(void*& pBuff)
Note that the function variable pBuff hides the global variable pBuff in the function set_data().
That said, I am unsure of the reason for void* and why vector<int> is not being used which handles all dynamic memory allocation for you.
When you say
pBuff = phy_bn;
You're just changing the local value of pBuff, not the global value of pBuff. Either pass pBuff as a double pointer, or simply remove the argument to the function, as pBuff is global already.
void *pBuff = 0; /* This is the global pBuff, which isn't being changed */
void set_data(void *pBuff /* This is the local pBuff, which is being changed */)
{
...
pBuff = phy_bn;
...
}
'plz i want to avoid double pointers..its not required i guess...'
Guessed wrong, it is required! You'll need a pointer reference for the pBuff parameter then:
void set_data(void*& pBuff)
{
// ...
}
This is effectively the same as using a double pointer.
The only thing you're doing with
pBuff =phy_bn;
is manipulating the function parameter representation on the local stack.
The pBuff inside set_data is not the global pBuff. The value of the global pBuff never gets changed from 0. Since this is C++ code, set_data can take its pointer argument by reference, and assigning to it will change the value at the point of the function call.
In C++, pointers are passed by value, the same as other value types. It may be instructional to think of a pointer as literally an integer type; then it’s easy to see why pBuff = phy_bn; doesn’t accomplish anything, for the same reason that this code doesn’t:
#include <iostream>
void set(int x) {
x = 5;
}
int main(int argc, char** argv) {
int y = 0;
set(y);
std::cout << y << '\n';
return 0;
}
Here, x is a local variable. It is a copy of y, not y itself. You can change its value by assigning to it, sure, but you’re merely changing the value of a variable which will not exist outside the scope of set(). If you change the definition of set() to use a reference:
void set(int& x) {
x = 5;
}
Then y will indeed be updated, because you have explicitly requested that x be an alias for the name you pass to set(), instead of a copy. You were misled by the names: the pBuf in set_data() is not the same variable pBuf in main(), even though they happen to have the same value; they’re like two different people with the same name and the same amount of money.