On Pointers and Dereferencing - c++

I've been working on learning C++ lately and picked up the book "C++ Through Game Programming". I'm on the chapter on Pointers and I've been presented an example that I have a question about. The code is this:
#include "stdafx.h"
#include <iostream>
using namespace std;
void badSwap(int x, int y);
void goodSwap(int* const pX, int* const pY);
int main()
{
int myScore = 150;
int yourScore = 1000;
cout << "Original values\n";
cout << "myScore: " << myScore << "\n";
cout << "yourScore: " << yourScore << "\n\n";
cout << "Calling badSwap()\n";
badSwap(myScore, yourScore);
cout << "myScore: " << myScore << "\n";
cout << "yourScore: " << yourScore << "\n\n";
cout << "Calling goodSwap()\n";
goodSwap(&myScore, &yourScore);
cout << "myScore: " << myScore << "\n";
cout << "yourScore: " << yourScore << "\n";
cin >> myScore;
return 0;
}
void badSwap(int x, int y)
{
int temp = x;
x = y;
y = temp;
}
void goodSwap(int* const pX, int* const pY)
{
//store value pointed to by pX in temp
int temp = *pX;
//store value pointed to by pY in address pointed to by pX
*pX = *pY;
//store value originally pointed to by pX in address pointed to by pY
*pY = temp;
}
In the goodSwap() function there's the line:
*pX = *pY;
Why would you dereference both sides of the assignment? Isn't that the equivalent of saying "1000 = 150"?

Why would you dereference both sides of the assignment? Isn't that the equivalent of saying "1000 = 150"?
No, just like the following:
int x = 1000;
int y = 150;
x = y;
is not the equivalent of saying "1000 = 150". You're assigning to the object, not to the value it presently contains.
The below is precisely the same (since the expression *px is an lvalue referring to the object x, and the expression *py is an lvalue referring to the object y; they're literally aliases, not some strange, disconnected version of the objects' numerical values):
int x = 1000;
int y = 150;
int* px = &x;
int* py = &y;
*px = *py;

*px=*py means we are assigning the value not address, from address of py to address of px.

Skip the chapter of the book or buy another one:
there is no need of using plain pointers in C++ nowadays.
Also there is a std::swap function, that does the things C++isch.

Related

why this pointer value not printed?

i have a code:
#include <iostream>
using namespace std;
int main()
{
int *a, y = 6 , *yPtr = &y;
cout << "y:" << y << "| &y:" << &y << "| yptr:" << yPtr << "| *yptr:" << *yPtr << " | &yptr:" << &yPtr << " |a:" << a << endl;
*a = y;
cout<< "a:"<<a<<endl;
return 0;
}
when i assign *a to y *a = y then *a value not printed for me
This is because you never initialize a itself. *a points to who-knows-where, some random location. So you set some random location to 6.
As it's probably pointed outside of legal space, your program is probably quitting before it gets to the cout statement.

C++ How works set of function's argument value?

I am learning C++ and I have code:
float x, y;
namespace X {
void SetMyX(float p) {
x = p;
}
void SetMyY(float p) {
y = p;
}
namespace XY {
void Set(float p = 0.0f) {
x = p;
p = y;
}
}
}
int main() {
X::SetMyX(5.4f);
std::cout << "x = " << x << " y = " << y << std::endl;
X::SetMyY(4.1f);
std::cout << "x = " << x << " y = " << y << std::endl;
X::XY::Set();
std::cout << "x = " << x << " y = " << y << std::endl;
return 0;
}
And output is:
x = 5.4 y = 0
x = 5.4 y = 4.1
x = 0 y = 4.1
And I figure out variable p sets value of x and then y sets value of p? But, how it is possible? In C++ you can also set value of function's argument or what?
It's just weird for me because I thought you can't just "editing" entered value and you must add another variable like result or something like that, or just return sum of two arguments, but change them?
Yes, the argument p is a completely normal variable and you can do everything with it.
This will also work in many other languages like C, Java, Javascript or Python.

Changing pointers in functions [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 4 years ago.
I am new to c++ coding and this question may seem childish to you all. But I am really not able to come up on a solution to my problem. Please help.
#include <iostream>
using namespace std;
int* getnew(int* x){
int temp = *x;
int* y = &temp;
cout << "from function address of y = " << y
<< " and value of y = " << *y << endl;
return y;
}
int main(){
int x = 100;
int* y = getnew(&x);
cout << "address of y = " << y;
cout << " and value of y = " << *y << endl;
return 0;
}
Output of this code :
from function address of y = 0x7ffee52aa914 and value of y = 100
address of y = 0x7ffee52aa914 and value of y = 1
What I thought should be the output :
from function address of y = 0x7ffee52aa914 and value of y = 100
address of y = 0x7ffee52aa914 and value of y = 100
Can someone explain where am I going wrong ?
Since you’re getting the address of temp, wich was declared inside a function, it’s scope belongs only to the function.
So, when you leave get_new() the temp var no longe exists ( get deallocated ). Then when you acess the same address ( the temp address) in main you access a space of memory that isn’t reserved, wich means that that space can be freely used by other vars and stuff of the program.
Try to use malloc to allocate a new space of memory and guarantee that the var still lives after the get_new returns (finishes). Here’s a example:
#include <iostream>
using namespace std;
int* getnew(int* x){
int temp = *x;
// return a memory address pointing to a ‘ sizeof(int )’ bytes reserved space.
int *y = malloc( sizeof(int) );
cout << "from function address of y = " << y << " and value of y = " << *y << endl;
return y;
}
int main(){
int x = 100;
int* y = getnew(&x);
cout << "address of y = " << y;
cout << " and value of y = " << *y << endl;
return 0;
}
EDIT:
Also do not forget to deallocate the memory when you're finished using it ( no longer needs it):
#include <iostream>
using namespace std;
int* getnew(int* x){
int temp = *x;
// return a memory address pointing to a ‘ sizeof(int )’ bytes reserved space.
int *y = malloc( sizeof(int) );
cout << "from function address of y = " << y << " and value of y = " << *y << endl;
return y;
}
int main(){
int x = 100;
int* y = getnew(&x);
cout << "address of y = " << y;
cout << " and value of y = " << *y << endl;
/*********** same code until here********/
//use free for each memory allocated by malloc()
free(y); //deallocates the memory pointed by *y*
free(other_y_if_it_exists);
return 0;
}

C++ Swapping Pointers

I'm working on a function to swap pointers and I can't figure out why this isn't working. When I print out r and s in the swap function the values are swapped, which leads me to believe I'm manipulating a copy of which I don't understand because I pass by reference of p and q.
void swap(int *r, int *s)
{
int *pSwap = r;
r = s;
s = pSwap;
return;
}
int main()
{
int p = 7;
int q = 9;
swap(&p, &q);
cout << "p = " << p << "q= " << q << endl;
return 0;
}
Prints: p = 7q = 9
Inside your swap function, you are just changing the direction of pointers, i.e., change the objects the pointer points to (here, specifically it is the address of the objects p and q). the objects pointed by the pointer are not changed at all.
You can use std::swap directly. Or code your swap function like the following:
void swap(int *r, int *s)
{
int temp = *r;
*r = *s;
*s = temp;
return;
}
The accepted answer by taocp doesn't quite swap pointers either. The following is the correct way to swap pointers.
void swap(int **r, int **s)
{
int *pSwap = *r;
*r = *s;
*s = pSwap;
}
int main()
{
int *p = new int(7);
int *q = new int(9);
cout << "p = " << std::hex << p << std::endl;
cout << "q = " << std::hex << q << std::endl << std::endl;
swap(&p, &q);
cout << "p = " << std::hex << p << std::endl;
cout << "q = " << std::hex << q << std::endl << std::endl;
cout << "p = " << *p << " q= " << *q << endl;
return 0;
}
Output on my machine:
p = 0x2bf6440
q = 0x2bf6460
p = 0x2bf6460
q = 0x2bf6440
p = 9 q= 7
The line r=s is setting a copy of the pointer r to the copy of the pointer s.
Instead (if you do not want to use the std:swap) you need to do this
void swap(int *r, int *s)
{
int tmp = *r;
*r = *s;
*s = tmp;
}
You passed references to your values, which are not pointers. So, the compiler creates temporary (int*)'s and passes those to the function.
Think about what p and q are: they are variables, which means they are slots allocated somewhere in memory (on the stack, but that's not important here). In what sense can you talk about "swapping the pointers"? It's not like you can swap the addresses of the slots.
What you can do is swap the value of two containers that hold the actual addresses - and those are pointers.
If you want to swap pointers, you have to create pointer variables, and pass those to the function.
Like this:
int p = 7;
int q = 9;
int *pptr = &p;
int *qptr = &q;
swap(pptr, qptr);
cout << "p = " << *pptr << "q= " << *qptr << endl;
return 0;
You are not passing by reference in your example. This version passes by reference,
void swap2(int &r, int &s)
{
int pSwap = r;
r = s;
s = pSwap;
return;
}
int main()
{
int p = 7;
int q = 9;
swap2(p, q);
cout << "p = " << p << "q= " << q << endl;
return 0;
}
Passing by reference is not the same as passing by value or by pointer. See C++ tutorials on the web for an explanation. My brain is too small to waste cells storing the fine details I can find on the web easily.
If you are into the dark arts of C I suggest this macro:
#define PTR_SWAP(x, y) float* temp = x; x = y; y = temp;
So far this has worked for me.

Why does changing what a reference points to not throw an error?

Iv got to the stage in my c++ study concerning references. It states the following rule:
Once a reference is initialized to an object, it cannot be changed to refer to another object.
Iv wrote a short code (as asked to in an exercise) that is meant to prove this rule correct.
int y = 7;
int z = 8;
int&r = y;
r = z;
Can someone explain why this code compiles without any errors or warnings?
r = z does not change what r "points to." It assigns the value of z to the object pointed to by r.
The following code does the same thing as your code, but using pointers instead of references:
int y = 7;
int z = 8;
int* p = &y; // p points to y
*p = z; // assign value of z to the object pointed to by p (which is y)
It does not make the reference alias to something else but it changes the value of what r contains.
int&r = y;
ris reference to y
r = z;
changes value of y & r to value of z by assigning value of z to r & hence y.
int&r = y;
r = z;
It does NOT change the reference. Rather it changes the value pointed to by the reference variable. The reference variable is just yet another name of y. So r=z is equivalent to
y = z;
That is, r=z changes the value of y.
Reference variable cannot be reset to refer to another variable, in any way.
You're not changing the reference; you're setting a new value to the referred object. After this example you should note that y==8.
When you do r = z you are not reseating the reference, instead you are copying the value of z into y.
I faced the same issue when study <<thinking in c++> charpter11.
here is my understanding code: the second compile error seems can not be simulated. but can understand. you can draw a picture to see what x, y, z, and ref2 point to.
/**
Write a program in which you try to
(1) Create a reference that is not initialized when it is created.
(2) Change a reference to refer to another object after it is initialized.
(3) Create a NULL reference.
**/
#include <iostream>
using namespace std;
int main() {
// 1
//int& ref1; // compile error:
int x = 10;
int& ref2 = x;
cout << "x = " << x << endl;
cout << "ref2 = " << ref2 << endl << endl;
// 2
int y = 20;
ref2 = y; // 这里没有编译错误,ref2的指向并未改变,其指向的空间由10改变为20
cout << "ref2 = " << ref2 << endl;
cout << "x = " << x << endl;
cout << "y = " << y << endl << endl;
int z = 30;
ref2 = z;
cout << "ref2 = " << ref2 << endl;
cout << "x = " << x << endl;
cout << "y = " << y << endl;
cout << "z = " << z << endl;
// 3
//int& ref3 = NULL; // compile error:
return 0;
}