It's been a while since I've coded anything in C++. While I was trying to help another person as a CIS Tutor, he wanted to know why it's necessary to have an ampersand next to a pointer to an int.
I figured that if you were to pass a pointer by reference and you point to something else, the main knows after you passed that val will equal to whatever you set it equal to.
There will be an example below will demonstrate what I'm trying to say.
Is this correct?
//main function
int variable = 0;
int* val = &variable;
function1(val);
cout << *val << endl;
function2(val);
cout << *val << endl;
//Passing in a pointer with reference.
void function1(int*& value)
{
int variable = 9;
value = &variable;
}
//Passing in a pointer without reference.
void function2(int* val)
{
int variable = 9;
value = &variable;
}
My assumption is that the program will output 9 instead of 8 or 0. I hope this give you guys a clear picture of what I'm trying to ask.
The difference between passing the values and passing the reference is the same with pointers as with other values (actually pointers are nothing special they just hold numbers that sometimes are adresses of other objects).
With int:
void foo(int x) { x = 1; }
void bar(int& x) { x = 2; }
int main() {
int y = 5;
foo(y);
std::cout << y; // prints 5
bar(y);
std::cout << y; // prints 2
}
Now with pointers:
void foo(int* x) { x = 0; }
void bar(int*& x) { x = 0; }
int main() {
int y = 42;
int* z = &y;
foo(z);
std::cout << z; // prints the address of y
bar(z);
std::cout << z; // prints 0
}
Note that your function1 is broken, because when you call it
int* y;
function1(y);
std::cout << *y; // **baaam**
// the value y points to is already gone
the int inside the function ends its lifetime when the function returns and the caller cannot use the value in any meaningful way. Note that in this particular example you would probably get the "correct" value printed, but that is just by coincidence and dereferencing y after passing it to function1 is undefined behaviour.
Related
I am getting an illegal hardware instruction error when compiled on mac. Appreciate any pointers.
#include<iostream>
using namespace std;
int * fun(int * x)
{
return x;
}
int main()
{
int * x;
*x=10;
cout << fun(x);
return 0;
}
Pointers are just pointers. In your code there is no integer that you could assign a value to.
This
int * x;
Declares x to be a pointer to int. It is uninitialized. It does not point anywhere. In the next line:
*x=10;
You are saying: Go to the memory that x points to and assign a 10 to that int. See the problem? There is no int where x points to, because x doesnt point anywhere. Your code has undefined behavior. Output could be anything.
If you want to assign 10 to an int you need an int first. For example:
#include<iostream>
using namespace std;
int * fun(int * x)
{
return x;
}
int main()
{
int y = 0;
int * x = &y;
*x=10;
cout << fun(x);
return 0;
}
This assigns 10 to y. The cout is still printing the value of x, which is the adress of y. It does not print the value of y. Not sure what you actually wanted.
The problem is that in your program the pointer x is not pointing to any int variable. So first you have to make sure that the pointer x points to an int object as shown below.
You can sovle this as shown below:
int i = 0; //create the int object to which x will point
int *x = &i; //make x point to variable i
*x = 10; //dereference the pointer x and assign 10 to the underlying variable i
cout << *fun(x); //this prints 10
I'm having a hard time understanding how this example from the w3schools tutorial works.
#include <iostream>
using namespace std;
void swapNums(int &x, int &y) {
int z = x;
x = y;
y = z;
}
int main() {
int firstNum = 10;
int secondNum = 20;
cout << "Before swap: " << "\n";
cout << firstNum << secondNum << "\n";
// Call the function, which will change the values of firstNum and secondNum
swapNums(firstNum, secondNum);
cout << "After swap: " << "\n";
cout << firstNum << secondNum << "\n";
system("pause");
return 0;
}
I think I understand the first part:
void swapNums(int &x, int &y) {
int z = x;
x = y;
y = z;
}
I'm basically referencing whatever x and y are going to be when I call the function. So x is going to be "pointing" to firstNum and y is going to be pointing to secondNum. It's going to do the switcheroo using a third variable as a placeholder.
However, after I call the function swapNums(firstNum, secondNum);, I don't understand how the function with its local variables has the ability to change the values of int firstNum = 10; and int secondNum = 20;.
My understanding is that variables within a function are "local" and the scope of said variables only extend within the function itself. How do the local variables change other variables outside their own function without any return statements?
Try this
#include <iostream>
void change_val_by_ref(int &x)
{
x=100
}
void change_val_by_val(int x)
{
x=50;
}
int main()
{
int whatever=0;
std::cout<<"Original value: "<<whatever<<"\n";
change_val_by_ref(whatever);
std::cout<<"After change by ref: "<<whatever<<"\n";
change_val_by_val(whatever);
std::cout<<"After change by val: "<<whatever<<"\n";
}
The output you will see is:
0
100
100
Let's see what happened
change_val_by_ref changed the original whatever, because the ref
was "pointing" to the VARIABLE.
change_val_by_val didn't change the whatever, because the argument of the function x has just copied the value of whatever, and anything that happens to x will not affect whatever, because they are not related.
That's the point of passing by ref.
Imagine you have banana and orange placed in two different plates. You place them into big box with a robotic hand.
You, obviously, can change their destination using you hand. But you want the robotic hand to do this task. You need to tell where the banana and orange are placed, so robotic hand can do its job. !Important robotic hand doesn't care about fruit, which is placed into these plates, it only cares about changing their positions.
By using a pointer, you just tell a function the placement of an object you want to change. And you can set your local, suitable name for this. So pointer is just the name of a plate, which contains a certain value.
References are syntactic sugar for passing around addresses of variables. Instead of the variable itself, you pass its memory address and then the function uses the address of the variable to change its value. Simple as that. Equivalent C code would be:
void swap(int* a, int* b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
I have 2 snippets of code, I am trying to pass a pointer into a function which is working for me, however when I deref the pointer, set to 10000 then increment I do not get the desired output.
#include<iostream>
void ReturnArray(int *matrix);
int array;
int main() {
ReturnArray(&array);
return(0);
}
void ReturnArray(int *matrix) {
int x{ 0 };
for (x=0; x < 10; ++x){
*matrix = 10000;
++matrix;
std::cout << *matrix << "\n";
}
}
However, when I increment the address of the pointer then set the value to 10000 the output is as expected..
#include<iostream>
void ReturnArray(int *matrix);
int array;
int main() {
ReturnArray(&array);
return(0);
}
void ReturnArray(int *matrix) {
int x{ 0 };
for (x=0; x < 10; ++x){
++matrix;
*matrix = 10000;
std::cout << *matrix << "\n";
}
}
Thanks!
array is a single integer, you are trying to use it as a 10 element array, this is undefined behaviour. Any result is possible.
Change array to be an array:
int array[10];
To make your code print the correct values you need to increment after printing:
for (x=0; x < 10; ++x) {
*matrix = 10000;
std::cout << *matrix << "\n";
++matrix;
}
ok so figured it out, I am setting the value after deref, then changing the address so when cout is called there is nothing initialized at that new address...
I guess my next question then is.. where is the 4 coming from? is it termed garbage data or is there a reason it is not 0?
thank-you for helping me understand.
So I'm trying to familiarise myself with c++ pointers by running the following code.
#include <iostream>
using namespace std;
int main(void){
int* x;
cout << &x << endl;
return 0;
}
which works fine and prints the pointer value of x but
#include <iostream>
using namespace std;
int main(void){
int* x;
*x = 100;
cout << &x << endl;
return 0;
}
gives me a segmentation fault when I try to tun it. Why is this? I don't see how that extra line should change anything about the address of x.
You did not allocate an object which you are going to assign.
int* x;
The value of x is unspecified and can be any arbitrary value. So the next statement
*x = 100;
is invalid.
You have to write
x = new int;
*x = 100;
Or
x = new int( 100 );
Or even
x = new int { 100 };
provided that your compiler supports the list initialization for operator new which was introduced in the C++ 2011..
and prints the pointer value of x but
Not exactly.
std::cout << &x; it prints x's address (the pointer's address);
std::cout << x; prints the address, x points to;
std::cout << *x; prints what x points to;
int* x;
*x = 100;
Here, x is just a pointer, you need to allocate memory for the 100. For example
int* x = new int;
*x = 100;
std::cout << *x;
Or just
int* x = new int( 100 );
std::cout << *x;
Without allocating memory and leaving x uninitialized, by *x = 100 you're trying to change some random memory, which leads to undefined behavior.
You have undefined behaviour.
Your first example is fine since &x (which has type int**) is the address of a stack allocated pointer. One of the << overloads in cout is defined to output that correctly.
In the second example, you are dereferencing a pointer that is not pointing to anything. That's undefined behaviour; hence the crash. If you'd written
int y;
int* x;
x = &y;
*x = 100; /*this means that y is now 100*/
then all would have been well since now x is pointing to something.
int main()
{
int x = 2, y = 4;
func(&x, &y);
printf("%d %d\n", x, y);
return 0;
}
void func(int *x, int *y)
{
int *temp;
temp = x;
x = y;
y = x;
}
Hi
For this code i have no idea why the output is 2 4 instead of 4 4. Since x = y in func() means x now points to the address of y, and y = x in func() means y now points to the address of x (which is y), both variables are now pointing to y already.
Many thanks!
The answer is simple: You change the pointer values inside func - but not the values they point at. I guess you'd like to swap the variables (due to the temp var).
This code should work (swapping values):
void func(int *x, int *y)
{
int temp = *x; // dereferencing the pointer to get the value it points at.
*x = *y;
*y = temp;
}
Too keep your initial expectations (which don't make any sense code wise due to the second assignment):
void func(int *x, int *y)
{
*x = *y;
*y = *x;
}
Nope, func() will receive copies of those addresses and this won't affect the variables outside the function - all changes done to variables local to func() will be discarded once func() exits.
You are just temporarily assigning the address of 'x' to the address of 'y' within func. In order to make the assignment, you need to dereference your pointers.
*x = *y;
*y = *x;
Try this
#include <iostream>
using namespace std;
void func(int *x, int *y);
int main()
{
int x = 2, y = 4;
func(&x, &y);
//printf("%d %d\n", x, y);
cout << "X - " << x << endl;
cout << "Y - " << y << endl;
return 0;
}
void func(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
You're making copies of the passed in pointers, they are local to your function. Any change you make to them doesn't affect the outside. You should capture the pointers by reference &.
void func(int*& x, int*& y){
// as before...
}
Now the changes inside the function will be correctly reflected outside of it. On problem remains though. You're passing in the address of local variables, and attempt to change their pointers - that doesn't work. When you take the address of a variable &x, you make a new temporary pointer, which can't be converted to a reference-to-pointer.
Do this instead:
int main(){
int x = 2, y = 4;
int *px = &x, *py = &y;
func(px, py);
printf("%d %d\n",*px,*py);
}
Edit: If you instead want to swap / set the values of x and y and not just some pointers, do as the other answers state.
The problem is that you're trying to write your own version of std::swap. This will work:
int x = 2, y = 4;
std::swap(&x, &y);
printf("%d %d\n", x, y);
return 0;