Why is the array changed after this function call? [duplicate] - c++

This question already has answers here:
What is array to pointer decay?
(11 answers)
Closed 5 years ago.
In the following program, the value of the first element of array x prints as zero after passing the array as parameter to some function which modifies its parameters. The same does not happen to the int variable y, a modification in another function goes unnoticed in the calling function. Thus I was expecting the array to retain its values before the function call, just like it happens with y. Why is the array changed while the variable is not?
void func1 (int x[]){
x[0]=0;
}
void func2(int y){
y=0;
}
int main(){
int x[]={7}, y=8;
func1(x);
func2(y);
cout << x[0] << y;
return 0;
}
output:
08
expected:
78

The parameter int[] is exactly the same as int*, a pointer to an int. The array passed to the function decays to such pointer to the first element of the array, thus dereferencing it through the subscript operator and modifying the int pointee results in the original being modified.

for you information i am putting values in comment in front of every line
void func1 (int x[]){
x[0]=0;//x here has same address as in main function so changes can be //directly apply to the original value of x array
//x[0]=7 was passed in this function is now modified by have a value x[0]=0
}
void func2(int y){
y=0;//but y is a different variable in this function it is not the same y in main function so if you change its value it does not mean that you are changing the value of y in main function so it does not give you the expected output
// it is due to local variable concept y in func2 is different and y in main is a different so all you have to do is to pass address of y variable so that if you want to change any thing is y will directly change its value in main function
}
int main(){
int x[]={7}, y=8;
func1(x);
func2(y);
cout << x[0] << y;
return 0;
}

Array use contiguous memory location to store data.
When you are calling func1(int x[]) then the previous value changing with value given by function and the location remaining same, so
in main function
x[0]=7
after function call
x[0]=0
thats why your array value getting changed.
And for the variable you didn't return anything thats why no change for it.
So 08 is correct output for this case

Related

friend function is not assigning values to class's array [duplicate]

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;
}

C++ pointers and addresses

i was just playing with pointers as function arguments and i know this.
#include <iostream>
using namespace std;
void func(int *a)
{
*a+=1;
return;
}
int main()
{
int a=1;
cout<<a<<endl;//prints 1
func(&a);
cout<<a;//prints 2
return 0;
}
My question is why does below code act similar to the one above, more precisely
when we call func(&a) from main function in above case
// starting address of that 4 bytes(size of int) of data gets passed and in our function(func) this address is stored in local pointer 'a' and when we write *(a) our compiler knows to read 4 bytes of data because its an integer pointer.
in short, my question is
what exactly are we passing to 'func'
when we call func(a) where 'a' is a variable which stores an integer value
and what exactly func(int &a) means
#include <iostream>
using namespace std;
void func(int &a)
{
//cout<<*a;// error
a+=1;
// cout<<a<<endl;
}
int main()
{
int a=1;
cout<<a<<endl;// prints 1
func(a);
cout<<a;// prints 2
return 0;
}
sorry for bad english
One way to read pointers and references is that during declarations, the '*' can be replaced by "something that points to".
So:
int* a;
Means that 'a' is something that points to an integer (i.e. 'a' is a pointer).
In other places in the code (not declarations), the '*' can be replaced by "the thing pointed to by".
So:
*a = 5;
Means that "thing pointed to by 'a' becomes equal to 5". I.e. the integer which a points to is now 5.
In your first block of code, 'a' is just an integer type. when you write func(&a);, you are passing the address of 'a' (i.e. the name of the memory location which stores the value of 'a') to the function. The function is expecting an int* type, (something which points to an int), which is exactly what you've given it.
Within the function, 'a' is just the address of your variable. The function then takes this address, and says "increment the thing that 'a' points to".
In your secondblock of code, 'a' is again just an integer type. This time however, the function is expecting a reference variable (because the function definition is expecting an int& type.
So within the function, 'a' is the original variable - not a copy or a pointer to the original variable. The function says "increment the actual integer that was sent".
Read more
The two cases work similarly:
Case 1: func expects some pointer to some direction of an integer (int *a) which is, as you said, the first byte of a sizeof (int) bytes block according to the OS. When func is called you passed correctly that direction func(&a), so the compiler considers that call as something like: int p = &a; func(p); anyway a pointer to that direction is actually what is being passed.
Case 2: func expects some direction of some integer (int &a). When func is called you just passed correctly the value func(a), as all C++ compilers support reference paramenters, the compiler passes internally the direction of the passed value, func (&a). Notice if you try to call func like func (&a) an error will occur because it would be passed something like func (&&a) while the compiler is just waiting for (&a).
OBS: We can also look to the second case void func(int &a) as a reference which is different from a pointer with an example:
int a = 10;
int &b = a;
cout<<a; //10 is printed
cout<<b; //10 is printed
b = 20;
cout<<a; //20 is printed
cout<<b; //20 is printed
Whether you modify a reference to a (i.e b) or you modify a directly, you are modifying the same value beacause they stand at the same direction of a.

const_cast doesn't change the value [duplicate]

This question already has answers here:
const_cast doesn't work c++? [duplicate]
(3 answers)
Closed 6 years ago.
After const_cast, the value does not change in the main function. But changes when calling an external function, still prints the old value in the main (where const int is initialized first).
int main() {
const int i = 5;
int* p = const_cast<int*>(&i);
*p = 22;
std::cout<<i;
return 0;
}
Output is 5, why? The watch-window shows value of i = 22:
So why does it print 5 ? The output differs if I call an external function:
void ChangeValue(const int i) {
int* p = const_cast<int*>(&i);
*p = 22;
std::cout<<i; //Here the value changes to 22
}
int main() {
const int i = 5;
ChangeValue(i); //Value changes to 22 in the ChangeValue function
std::cout<<i // It again prints 5.
}
Why is the value not changed even if the value changes after calling the ChangeValue function?
I get the same output on a Linux Platform. Could someone please add clarity to my confusion?
Trying to modify a constant value leads to undefined behavior, just don't do it.
As for why it doesn't change, the compiler sees that it is a compile-time constant and may store it in a read-only segment.
For the second program, the variable i can't be stored in a read-only segment, it's stored on the stack like any other local variable. However, since you marked i as constant attempting to modify it is still undefined behavior.
The reason the main program prints the old value, is because you pass the variable by value meaning it gets copied into the local variable i in the ChangeValue function. If the variable wasn't a constant in the main or the ChangeValue function, the value of i in the main function would still not change.
If you change the ChangeValue function to take its argument by reference, you might get the same behavior as the first program.

sizeof() returning different values when called on the same array in the main function and another function [duplicate]

This question already has answers here:
When a function has a specific-size array parameter, why is it replaced with a pointer?
(3 answers)
Closed 9 years ago.
I need the use the length of a passed array 'X' in a function. The array is created in the main function. I print out the following from the main function:
std::cout << "\n" << sizeof(X);
which yields: 400
The array 'X' is then passed to a function where the length of X is needed. I print out the following from the function:
std::cout << "\n" << sizeof(X);
which yields: 8
I am expecting 400, as my array has 100 float elements. Why does sizeof() not return the same size as when it was called in the main function? (I assure you that there are actually 100 elements in array X because the rest of the program works.)
Thanks for any help!
When you pass a raw array (e.g. declared as int arr[100];) as a parameter to some other function, is it decayed into a pointer (whose size is often 8 on 64 bits processor).
So you declare your array
int arr[100];
then you declare your function
void f(int arr[]);
which is understood as
void (int *arr);
In C++11 you could use std::array so declare
std::array<int,100> arr;
and pass preferably a reference to it:
void f(std::array<int,100> &arr);
(you could pass it by value, but then all the 100 integers would be copied on function invocation).
BTW, consider also std::vector, and take many hours to read a good C++ programming book.
C arrays can be implicitly reduced to pointers and they will be. For sizeof to work correctly you would need to do the following:
template<size_t N>
void func(char (&arr)[N])
{
/* sizeof(arr) == N in this scope */
}
or you could use C++11 std::array.
In main the array size will be 4*100 = 400, but when you pass the address of array to another function it is now a pointer pointing to array, meaning the size of X is now size of pointer in called function.

Assigning function to variable

Why assign a function to a variable? What's the point in assigning int x, y to ReadNumber() ? Is it for storing return value of function in a variable? Or is this just a way to pass arguments?
#include <iostream>
int ReadNumber()
{
using namespace std;
cout << "Enter a number: ";
int x;
cin >> x;
return x;
}
void WriteAnswer(int x)
{
using namespace std;
cout << "The answer is " << x << endl;
}
int main()
{
int x = ReadNumber();
int y = ReadNumber();
WriteAnswer(x+y);
return 0;
}
"why does he assign a function to a variable?"
He doesn't. This(note the brackets):
// vv
int x = ReadNumber();
assigns the returned value to x. The brackets mean, that the function is actually called - or the body is executed. That function has return x; at the end, so it returns the value of x which is assigned to x - the one in the main. Note that the x in main and x in ReadNumber are totally different.
Also, you can't assign function to a variable in C++ (you can use function pointers, but this is another thing)
"What's the point in assigning int x, y to ReadNumber() ?"
The returned value from ReadNumber is a temp value and it should be stored somewhere. So, that's why x and y are defined in the main, so that each of them stores the value, returned from ReadNumber. And each of these values can be different.
If, in main, there were no x and y, the returned values are unusable and cannot be accessed at all. And they are destroyed.
"Is it for storing return value of function in a variable? Or is this just a way to pass arguments?"
No any arguments here. Arguments are written inside the brackets ( () ) and here, there are no such when calling ReadNumber. So yes, they are for storing the returned values.
WriteAnswer does not have return at the and and it's defined as void - which means - no return value. That's why there's no such thing as
int x = WriteNumber( X + y )
But note, that here WriteNumber has argument. Just one, and it's the value of the calculated x + y. So, it's like:
int z = x + y;
WriteNumber( x );
Yes, it is storing the return value of the function.
The code calls the ReadNumber function twice first. ReadNumber reads a string from the console then returns it as an int. The code stores the two function returns. It then adds these two numbers together and passes it as an argument to the WriteAnswer function. The WriterAnswer function takes the argument that was passed in and prints it out.
int x = ReadNumber();
By this statement, the programmer wants to assign the return value of that function to the variable. If you check the function signature, you can see that it returns a value of type int .
ReadNumber() reads a number from the standard input and returns it.
int x = ReadNumber();
stores that value into x.
Actually the function is not assigned to variable
What happened is each time ReadNumber() is called, it returns a number of type int. that number can be used anywhere, like putting in a variable like x, and we can call it one more time and assign the next value returned to another variable like y
The result of ReadNumber() is assigned to x - not the other way around. ReadNumber() asks the user for a number and assigns it to x, then for another number and assigns it to y. Then main() adds them together and shows the user using WriteAnswer().
He doesn't assign the function/method itself but the results...
He's assigning the results of two successive calls of method: ReadNumber() to the variables x and y respectively.
So the returned value of ReadNumber() is what is assigned.
See the return type of ReadNumber() is int - the same type as the variables being assigned.
I've commented the method below to make it clearer:
int ReadNumber()
{
using namespace std;
cout << "Enter a number: "; // This line prints the command to the standard output
int x;
cin >> x; // This line reads a number and assigns it to x
return x; // This line returns the number and ends the method...
}