Referencing a Double Pointer, what is the value? - c++

I cant figure out why the output of this program is what it is. Maybe some one can help me out.
And why does the reference of double Pointer: 0062FB78?
Why does the reference of dereferenced double pointer = 0062FAA0?
Should'nt these be flipped?
0062FB78 is the address of x
I am guess 0062FAA0 is the address of the double Pointer?
#include <iostream>
void print(int x) {
std::cout << "value: " << (x) << "\n";
std::cout << "reference: " << (&x) << "\n";
//std::cout << (*x) << "\n";
}
void printPointer(int *x) {
std::cout << "value: " << x << "\n";
std::cout << "reference: " << &x << "\n";
std::cout << "dereference:" << *x << "\n";
}
void printDoublePointer(int **x) {
std::cout << "value: " << x << "\n";
std::cout << "reference: " << &x << "\n";
std::cout << "dereference:" << *x << "\n";
printPointer(*x);
}
void printTripplePointer(int ***x) {
std::cout << "value:" << x << "\n";
std::cout << "reference:" << &x << "\n";
std::cout << "dereference:" << *x << "\n";
printDoublePointer(*x);
}
void print(char* string) {
std::cout << "\n" << string << "\n";
}
int main()
{
int x = 19;
int *y; // y is a address space
y = &x; // &y now points to the address of x, *y now has the value of x
int **doublePointer = &y;
print(x);
printPointer(y);
printDoublePointer(doublePointer);
print("doublePointer");
std::cin >> x;
}
x
value: 19
reference: 0062FBB78
y
value: 0062FC7C
reference: 0062FBB78
defererence: 19
doublePointer
value: 0062FC58
reference of double Pointer: 0062FB78
dereference of doble Pointer: 0062FC7C
value of dereferenced double pointer: 0062FC7C
reference of dereferenced double pointer: 0062FAA0
dereference: 19

Before going over you problem, let's first agree that after calling y= &x, y is not a reference to x, but rather the address of x.
Now, let's examine the call to print
If you pay close attention, we pass the variable by-value, so this method will actually print the value 19, but the address will belong to a temp copy of x.
If we would have changed the prototype to the following one, the address of x printed here will be equal to the address of y printed in the method printPointer
void print(int & x) {
std::cout << __PRETTY_FUNCTION__ << "\n";
std::cout << "value: " << (x) << "\n";
std::cout << "reference: " << (&x) << "\n";
}
Regarding your other concern, these too occur because you pass the pointers by-value and not by-reference.
This simple program shows that everything works just fine:
int main()
{
int x = 19;
int *y = &x;
int **z = &y;
std::cout << x << "\t" << &x << std::endl;
std::cout << y << "\t" << &y << "\t" << *y << std::endl;
std::cout << z << "\t" << &z << "\t" << *z << std::endl;
}

Related

Questions about right value reference in C++

#include <iostream>
using namespace std;
void swap(int& a, int& b)
{
cout << "address of a: " << &a << " value of a: " << a << endl;
cout << "address of b: " << &b << " value of b: " << b << endl;
int tmp{move(a)};
cout << "address of tmp: " << &tmp << " value of tmp: " << tmp << endl;
a = move(b);
b = move(tmp);
cout << "address of a: " << &a << " value of a: " << a << endl;
cout << "address of b: " << &b << " value of b: " << b << endl;
}
void swap_no_move(int& a, int& b)
{
cout << "address of a: " << &a << " value of a: " << a << endl;
cout << "address of b: " << &b << " value of b: " << b << endl;
int tmp{ a };
cout << "address of tmp: " << &tmp << " value of tmp: " << tmp << endl;
a = b;
b = tmp;
cout << "address of a: " << &a << " value of a: " << a << endl;
cout << "address of b: " << &b << " value of b: " << b << endl;
}
int main() {
int a = 10;
int b = 5;
swap(a, b);
cout << endl;
int c = 10;
int d = 5;
swap_no_move(c, d);
cin.get();
return 0;
}
I have two swap functions: swap and swap_no_move. According to what I read from the book, there should be no "copy" in function swap which means the address of tmp should be the same for tmp and an in function swap. However, the output I got shows there is no difference between these two functions, did I do something wrong?
The definition
int tmp{move(a)};
doesn't move the reference or the variable a itself. It creates a brand new variable tmp which the compiler allocates space for. Then the value of a is moved into tmp.
And since moving int values can't really be done, it's exactly the same as
int tmp = a;

Pointers and references in functions

I have a problem with a school homework. I have to write a few function, and I have problem with the ShiftPointerVal which argument is a pointer to int. This is the most important in that homework, I mean that argument. I have that issue: error: lvalue required as left operand of assignment. Target of this function is to make a pointer bigger by one. I don't know how to write this function so the pointer to int can be an argument.
void ShiftPointerVal (int& pointer)
{
&pointer = &pointer + 1;
}
void ShiftPointerRef (int *&pointer)
{
pointer = pointer + 1;
}
void ShiftPointerPointer (int **pointer)
{
*pointer = *pointer +1;
}
int main ()
{
int number = 5;
int* p_number = &number;
std::cout << "\n----- 4 -----\n";
std::cout << &number << "\t" << p_number << "\n";
std::cout << *p_number << "\n";
ShiftPointerVal (p_number);
std::cout << &number << "\t" << p_number << "\n";
std::cout << *p_number << "\n";
std::cout << "\n----- 5 -----\n";
std::cout << &number << "\t" << p_number << "\n";
std::cout << *p_number << "\n";
ShiftPointerRef (*&p_number);
std::cout << &number << "\t" << p_number << "\n";
std::cout << *p_number << "\n";
std::cout << "\n----- 6 -----\n";
std::cout << &number << "\t" << p_number << "\n";
std::cout << *p_number << "\n";
ShiftPointerPointer (&p_number);
std::cout << &number << "\t" << p_number << "\n";
std::cout << *p_number << "\n";
}

What happens when I use *(int*)&x to assign to a constant value x? [duplicate]

This question already has answers here:
Modifying a const int in C++ [duplicate]
(2 answers)
Closed 5 years ago.
I have tried the following codes:
#include <iostream>
using namespace std;
struct MyClass {
const int x;
};
int main() {
MyClass c = {3};
const int *p = &c.x;
cout << "x = " << c.x << endl;
cout << "&x = " << &c.x << endl;
cout << "p = " << p << endl;
cout << "*p = " << *p << endl;
cout << "*(&x) = " << *(&c.x) << endl;
cout << endl;
*(int*)&c.x = 4;
cout << "x = " << c.x << endl;
cout << "&x = " << &c.x << endl;
cout << "p = " << p << endl;
cout << "*p = " << *p << endl;
cout << "*(&x) = " << *(&c.x) << endl;
cout << (p == &c.x) << endl;
cout << (*p == *(&c.x)) << endl;
return 0;
}
Then I get the following answer:
x = 3
&x = 0x61fe98
p = 0x61fe98
*p = 3
*(&x) = 3
x = 4
&x = 0x61fe98
p = 0x61fe98
*p = 4
*(&x) = 4
1
1
It seems that I have successfully change the value of constant integer x. But when I directly declare x in main() instead of in a class, I get the totally different answer.
#include <iostream>
using namespace std;
int main() {
const int x = 3;
const int *p = &x;
cout << "x = " << x << endl;
cout << "&x = " << &x << endl;
cout << "p = " << p << endl;
cout << "*p = " << *p << endl;
cout << "*(&x) = " << *(&x) << endl;
cout << endl;
*(int*)&x = 4;
cout << "x = " << x << endl;
cout << "&x = " << &x << endl;
cout << "p = " << p << endl;
cout << "*p = " << *p << endl;
cout << "*(&x) = " << *(&x) << endl;
cout << endl;
cout << (p == &x) << endl;
cout << (*p == *(&x)) << endl;
return 0;
}
The result is
x = 3
&x = 0x61fe98
p = 0x61fe98
*p = 3
*(&x) = 3
x = 3
&x = 0x61fe98
p = 0x61fe98
*p = 4
*(&x) = 3
1
0
That is really strange that (p == &x) is true but (*p == *(&x)) is false!!! I don't know what's going on in the second codes.
What you're doing is undefined behaviour, so anything can happen. The C++ standard says:
Except that any class member declared mutable (10.1.1) can be modified, any attempt to modify a const object during its lifetime (6.8) results in undefined behavior.
And:
[Note: Depending on the type of the object, a write operation through the pointer, lvalue or pointer to data member resulting from a const_cast that casts away a const-qualifier may produce undefined
behavior (10.1.7.1). — end note]
So you can cast away the "const" to get int* but attempting to actually modify the variable through that pointer is undefined.
The reason you can cast away the const is that it might not actually point to a constant:
int i = 0;
const int* p = &i;
*(int*)p = 1; // OK, because p points to a non-constant
const int j = 0;
const int* q = &j;
*(int*)q = 1; // NOT OK, because q points to a constant
In your second example the compiler is making assumptions when optimizing, based on the fact it knows that a constant value will not change, so it doesn't bother testing its value. The assumption is correct because a correct program can never change the value of a constant. Your program is not correct, but that means the compiler isn't required to give a sensible result.

c++ Functions (with body) as Argument

I want to pass an function as argument. I know you can pass a function pointer like the first test in my example, but is it possible to pass a hold function (not a pointer) like my second test?
#include <iostream>
using namespace std;
/* variable for function pointer */
void (*func)(int);
/* default output function */
void my_default(int x) {
cout << "x =" << "\t" << x << endl << endl;
}
/* entry */
int main() {
cout << "Test Programm\n\n";
/* 1. Test - default output function */
cout << "my_default\n";
func = &my_default; // WORK! OK!
func(5);
/* 2. Test - special output function 2 */
cout << "my_func2\n";
func = void my_func1(int x) {
cout << "x =" << " " << x << endl << endl;
}; // WON'T WORK! FAILED!
func(5);
return 0;
}
In C++ 11, you can pass a lambda:
func = [](int x) { cout << "x =" << " " << x << endl << endl; };
EDIT: lambdas can return values:
func = [](int x)->int{ cout << "x =" << " " << x << endl << endl; return x; };
With c++11, you can write such code in a lot simpler way:
Instead of writing function signature use auto
auto func = &my_default; // WORK! OK!
func(5);
you can also use std::function objects to pass them around:
template<typename T>
void callme(std::function<T> f) {
f(6);
}
std::function<decltype(my_default)> func1 = &my_default;
func(5);
callme(func1);
and also you can use lambdas:
/* 2. Test - special output function 2 */
cout << "my_func2\n";
auto fun = [](int x) {
cout << "x =" << " " << x << endl << endl;
};
fun(5);
Even with return value it work:
#include <iostream>
using namespace std;
/* variable for function pointer */
int (*func)(int);
/* default output function */
int my_default(int x) {
//cout << "x =" << "\t" << x << endl << endl;
return x;
}
/* entry */
int main() {
cout << "Test Programm\n\n";
/* 1. Test - default output function */
cout << "my_default\n";
func = &my_default; // WORK! OK!
cout << func(5) << endl << endl;
/* 2. Test - special output function 2 */
cout << "my_func2\n";
func = [](int x) {
//cout << "x =" << " " << x << endl << endl;
return x;
};
cout << func(5) << endl << endl;
return 0;
}
You can uses lamdas:
std::function<int(int)> func2 = [](int i) { return i+4; };
std::cout << "func2: " << func2(6) << '\n';
if the body consists of the single return statement, the return type
is the type of the returned expression (after rvalue-to-lvalue,
array-to-pointer, or function-to-pointer implicit conversion)
If you lamda constains not single return statamen you should specify return type
std::function<int(int)> func2 = [=](int i) ->int {
if (globalVar)
return i*4;
else
return 4;
};
std::cout << "func2: " << func2(6) << '\n';

Cannot call class function (parameterized class)

#include<iostream>
using namespace std;
class a
{
private:
int x;
int y;
public:
int getx()
{
return x;
}
int gety()
{
return y;
}
a()
{
x = 100;
y = 100;
}
void xmin()
{
x--;
}
void ab(a x)
{
x.xmin(); x.xmin(); x.xmin(); x.xmin();
}
};
void main()
{
a xx;
a yy;
cout << "xx" << endl;
cout << "x : " << xx.getx() << "y : " << xx.gety()<<endl;
cout << "yy" << endl;
cout << "x : " << yy.getx() << "y : " << yy.gety()<<endl;
xx.ab(yy);
cout << "xx" << endl;
cout << "x : " << xx.getx() << "y : " << xx.gety() << endl;
cout << "yy" << endl;
cout << "x : " << yy.getx() << "y : " << yy.gety() << endl;
}
Why the function x.xmin() in void ab(a x) cannot be executed properly? (The value of x didn't change as the function of xmin() decrease the value of x by 1.
This is the simple version of my code so that will be easier to understand :)
void ab(a x)
That takes its argument by value. The function modifies a local copy of the argument, so the caller won't see any changes. If you want the function to modify the caller's object, then pass by reference:
void ab(a & x)
^