I'm working with C++ pointers and I've encountered something curious.
If I reset a pointer to itself using "b = (int*)&b;", I expected the deferenced output to be the memory address of itself -- since it was pointing to itself.
So I thought *b would be "0x7ffea00819b0", but it's some strange numeric value.
But this isn't the case. The alternate value I get is confusing.
Here is my output:
Value of a = 10
Address of a = 0x7ffea00819ac
Value of b = 0x7ffea00819b0
Address of b = 0x7ffea00819b0
Dereference of b = -1610081872
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
int a = 10;
int *b = &a;
b = (int*)&b;
cout << "Value of a = " << a << endl;
cout << "Address of a = " << &a << endl << endl;
cout << "Value of b = " << b << endl;
cout << "Address of b = " << &b << endl;
cout << "Dereference of b = " << *b << endl;
}
Changing the type to unsigned long int fixed the issue.
Thank you all!
#include <iostream>
#include <type_traits>
using namespace std;
int main(int argc, char** argv)
{
unsigned long int a = 10;
unsigned long int *b = &a;
b = (unsigned long int*)&b;
cout << "Value of a = " << a << endl;
cout << "Address of a = " << &a << endl << endl;
cout << sizeof b << endl;
cout << sizeof *b << endl;
//static_assert(sizeof b == sizeof *b);
cout << "Value of b = " << b << endl;
cout << "Address of b = " << &b << endl;
cout << "Dereference of b = " << hex << "0x" << *b << endl;
}
Related
#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;
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.
int value = 3;
int *pValue1 = &value;
int *pValue2(pValue1);
cout << (*pValue1) << " " << (*pValue2);
In the above code if you have noticed I have written
int *pValue2(pValue1);
instead of
int *pValue2 = new int;
pValue2 = pValue1;
Still it is working and giving proper result.
Can any one explain to me which of the default function or constructor is getting called in this case?
int *pValue2(pValue1);
is equivalent to
int* pValue2 = pValue1;
Just assign to pValue2 pValue1 (assign to pValue2 address of variable value).
The difference should be apparent if you print the pointers themselves (the addresses) in addition to the values which they reference:
#include <iostream>
using namespace std;
int main() {
int value = 3;
int *pValue1 = &value;
int *pValue2(pValue1);
int *pValue3 = new int;
cout << pValue1 << " " << pValue2 << " " << pValue3 << endl;
cout << *pValue1 << " " << *pValue2 << " " << *pValue3 << endl;
pValue3 = pValue1;
cout << pValue1 << " " << pValue2 << " " << pValue3 << endl;
cout << *pValue1 << " " << *pValue2 << " " << *pValue3 << endl;
return 0;
}
You will also see that after new int, the memory pointed to by the pointer contains uninitialized data.
I am having problems with accessing individual structure elemnsts. How to output each structure element using pointer?
#include <iostream>
using namespace std;
struct student{
int rollno;
float marks;
char name[45];
};
int main(){
student s1[2]={{1,50.23,"abc"},{2,65.54,"def"}};
for(int j=0;j<2;j++){
cout<<"Output Rollno, Marks and Name Using Pointer"
}
return 0;
}
Just assign the address to a pointer, and print it.
student *ptr=s1; // or &s1[0], instead.
cout<<ptr->rollno;
You don't have a pointer.
To output the fields, you do what you'd do in any other situation, e.g.:
cout << "marks = " << s1[j] << "\n";
your loop should be something like:
for(int j=0;j<2;j++){
cout<<"Rollno:" << s1[j].rollno << " Marks:" << s1[j].marks << " Name:" << s1[j].name << endl;
}
or, using pointer (i.e. array + offset):
for(int j=0;j<2;j++){
cout<<"Rollno:" << (s1+j)->rollno << " Marks:" << (s1+j)->marks << " Name:" << (s1+j)->name << endl;
}
If you wanted to be real raw:
void* ptr = &s1[0];
for(int j=0;j<2;j++){
cout<< (int)*ptr << "," << (float)*(ptr+sizeof(int)) << "," << (char*)*(ptr+sizeof(int)+sizeof(float)) << endl;
}
char* p = (char* )s1;
for(int j=0;j<2;j++){
int* a = (int*) p;
cout << *a << " ";
a++;
float* b = (float*) a;
cout << *b << " ";
b++;
char* c = (char*) b;
cout << c << " ";
c = c + 45 + strlen(c);
cout<<endl;
p = c;
}
I'm trying to do a C-style string copy but something is not working right. What am I doing wrong?
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
int main() {
char string_a[20]="Good day!";
char string_b[30]="Hi!";
int i=0;
cout << "string a: " << string_a << endl;
cout << "string b: " << string_b << endl;
while (*string_a++ = *string_b++) {
cout << ++i << endl;
}
cout << "string a: " << string_a << endl;
cout << "string b: " << string_b << endl;
return 0;
}
You cannot do:
string_a++
if string_a is defined as an array. That only works for pointers and arrays decay to pointers only in specific circumstances.
If you change:
while (*string_a++ = *string_b++) {
cout << ++i << endl;
}
into:
char *pa = string_a, *pb = string_b; // a "specific circumstance" :-)
while (*pa++ = *pb++) {
cout << ++i << endl;
}
then it will work just fine, outputting:
string a: Good day!
string b: Hi!
1
2
3
string a: Hi!
string b: Hi!