I observe some weird behavior today , the code is as follow :
The Code :
#include <iostream>
struct text
{
char c;
};
int main(void)
{
text experim = {'b'};
char * Cptr = &(experim.c);
std::cout << "The Value \t: " << *Cptr << std::endl ;
std::cout << "The Address \t: " << Cptr << std::endl ; //Print weird stuff
std::cout << "\n\n";
*Cptr = 'z'; //Attempt to change the value
std::cout << "The New Value \t: " << *Cptr <<std::endl ;
std::cout << "The Address \t: " << Cptr << std::endl ; //Weird address again
return 0;
}
The Question :
1.) The only question I have is why cout theAddress for the above code would come out some weird value ?
2.)Why I can still change the value of the member c by dereferenncing the pointer which has weird address ?
Thank you.
Consider fixing the code like this:
std::cout << "The Address \t: " << (void *)Cptr << std::endl ;
There's a std::ostream& operator<< (std::ostream& out, const char* s ); that takes a char* so you have to cast to void* to print an address, not a string it "points" to
I think the "weird" stuff shows up because cout thinks it's a cstring, i.e. a 0-terminated character array, so it doesn't print the address as you expected. And since your "string" isn't 0-terminated, all it can do is walk the memory until it encounters a 0. To sum it up, you're not actually printing the address.
Why I can still change the value of the member c by dereferenncing the
pointer which has weird address
The address isn't weird, as explained above. In your code Cptr points to a valid memory location and you can do pretty much anything you want with it.
Related
This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Closed 2 years ago.
I am a newbie in c++ and my question may seem basic, but your answer could help me and help others.
I created to char pointer myPointer1 und myPointer2 so
const char *myPointer1 = "Hallo";
const char* myPointer2 = myPointer;
I thought that pointer stored the address of the variables they point to. In this case we have just one variable "Hallo" and both pointers should then points to the same address.
but when i print :
cout << &myPointer1 << endl << endl;
cout << &myPointer2 << endl << endl;
the results are two different adresses:
009EFC00
009EFBE8
Could anyone help?
You are printing the address of the pointer, not the address that the pointer points to.
std::cout << myPointer << std::endl;
This would print the address the pointer points to.
Since a char* is treated as a string when passed to std::cout it will print Hallo.
If you want to print the address itself you can achieve that by casting it to a const void* and printing that.
#include <iostream>
int main() {
const char *myPointer1 = "Hallo";
const char* myPointer2 = myPointer1;
std::cout << static_cast<const void*>(myPointer1) << std::endl;
std::cout << static_cast<const void*>(myPointer2) << std::endl;
}
After a pointer is initialized, do you have to use the * dereference operator to call the pointer in a condition?
Example:
int main()
{
int var = 10;
int *ptr = &var;
if(ptr) // does this need to be if(*ptr) ???
{.......}
}
And can I have a short explanation as to why?
Thank you.
if (ptr)
check if the pointer is not Null but
if (*ptr)
check if the value it points to is not zero (in this example is 10)
So for checking the value you shoud add *.
It depends on what you want to do.
if(ptr) checks if the pointer value is nullptr or not. Note that this is shorthand for if(ptr != nullptr).
if(*ptr) checks if what the pointer points to is nullptr (or 0) - and in that case, since you dereference (follow) the pointer to answer the question, the pointer itself had better not be nullptr in that case.
First of all, a pointer is only a variable. However, there are different contexts in which you can use it.
As any other variable you can access the pointers content (which is the adress of the underlying memory) as follows:
int i = 1;
int * p = &i;
std::cout << p << std::endl
this would output the adress of i since this is what is stored in p
If you however want to access the content of the underlying memory (the value of i), you need to dereference the pointer first by using the * operator:
std::cout << *p << std::endl;
This would print the value of iso 1.
of course you can also access the pointer's adress (since the adress of i is a numeric value as well and needs to be stored somewhere too):
std::cout << &p << std::endl;
That would output the adress of p so the adress where the adress of i is stored :)
As a little example try to run this code:
#include <iostream>
int main() {
int i = 1;
int * p = &i;
std::cout << "Value of i(i): " << i << std::endl
<< "Adress of i(&i): " << &i << std::endl
<< "Value of p(p): " << p << std::endl
<< "Dereferenced p(*p): " << *p << std::endl
<< "Adress of p(&p): " << &p << std::endl
<< "Dereferenced adress of p(*(&p)): " << *(&p) << std::endl;
}
My code:
#include <iostream>
using namespace std;
int main() {
char *test = (char*)malloc(sizeof(char)*9);
test = "testArry";
cout << &test << " | " << test << endl;
test++;
cout << &test << " | " << test << endl;
return 1;
}
Result:
004FF804 | testArry
004FF804 | estArry
I don't understand how it's possible that I had moved my array pointer and address didn't change.
The pointer did change. You're just not printing it. To print the pointer test:
cout << (void*) test << endl;
&test is the memory location where test is stored.
test is the value that you incremented with test++ (i.e., you didn't increment &test).
When you do cout << test the overload of operator<< that gets picked is one that takes a const char* and treats it as a C-style string, printing the characters it points to. The cast to void* avoids this behavior in order to print the actual value of test, instead of the value it points to.
In this statement
cout << &test << " | " << test << endl;
expression &test yields the address of the variable test itself that is evidently is not changed. It is the value stored in the variable was changed.
If you want to output the value of the variable test that is the value that points inside the string literal you should write
cout << ( void * )test << " | " << test << endl;
Take into account that there is a memory leak in the program because after allocating memory the pointer is reassigned. And sting literals have types of constant character arrays. So the pointer test should be declared like
const char *test;
When I tried to access the value(which is an address) stored in the address pointed by the pointer variable, a garbage value is returned. I have posted the code and the output below.
Code:
#include<iostream>
using namespace std;
int main(){
int *a, b=10, *c;
a = &b;
c = &b+1;
cout << "Address of A : " << &a << endl;
cout << "Value of A : " << a << endl;
cout << "Value pointed by A : " << *a << endl;
cout << "Address of B : " << &b << endl;
cout << "Value of B : " << b << endl;
cout << "Value of C : " << c << endl;
cout << "Value pointed by C : " << *c << endl;
return 0;
}
Output:
Address of A : 0x7fff3e608d20
Value of A : 0x7fff3e608d1c
Value pointed by A : 10
Address of B : 0x7fff3e608d1c
Value of B : 10
Value of C : 0x7fff3e608d20
Value pointed by C : 1046514972
In the above program, the address pointed by c is the address of a yet *c gives garbage value 1046514972 instead of 0x7fff3e608d1c.
I know, I can access the value of A in some other way but my question is why couldn't I access it in this way. Is this an expected behaviour? If yes, can somebody please explain? Thank you.
c = &b+1;
//...
*c
That's undefined behaviour. Forming a pointer to the location after a variable is valid, but performing indirection through it is not1. Even though some object happens to be there, the compiler is free to do whatever it wants.
As to why 1046514972 is printed, that's 0x3e608d1c in hex. It's just the bytes of the 64 bit pointer reinterpreted as a 32 bit integer. You just happen to get something which kind of makes sense, but since this is undefined behaviour, it's semantically garbage.
1 Technically it's the l-to-rvalue conversion which is undefined, but you don't have to worry about that.
I'm having some trouble understanding pointers. In the following code, I'm trying print the address of a variable in 2 ways-once using the address operator and then using pointers:
#include<iostream>
using namespace std;
int main (void)
{
int x = 10;
int *int_pointer;
int_pointer = &x;
cout << "x address=" << &x << endl;
cout << "x address w pointer=" << int_pointer << endl;
return 0;
}
x address = 0028FCC4
x address w pointer = 0028FCC4
This works as expected. But when I do the same thing but now using character type variable, I get some trash output:
#include<iostream>
using namespace std;
int main(void)
{
char c = 'Q';
char *char_pointer;
char_pointer = &c;
cout << "address using address operator=" << &c << endl;
cout << "address pointed by pointer=" << char_pointer << endl;
return 0;
}
address using address operator=Q╠╠╠╠£åbªp é
address pointed by pointer=Q╠╠╠╠£åbªp é
I have no idea why this is happening. Thanks in Advance.
The C++ library overloads the << operator for certain types. (char*) is one of them. Cout is trying to print a string, an array of characters terminated by a null character.
Just cast the pointer:
cout << "address pointed by pointer" << ( void* )char_pointer << endl;
or
cout << "address pointed by pointer" << static_cast<void*>(char_pointer) << endl;
The reason it prints out junky stuff is because your char does not have a null terminator which means the program will keep searching for one until, and in the process will print out whatever it finds. The text you see is ASCII but referenced by the address which the ostream is misinterpreting. To get the address held in memory, you could use implicit conversion or a static_cast. I prefer the latter:
cout << "address pointed by pointer=" << static_Cast<void*>(char_pointer) << endl;
Like 2501 said, in different wording, &c, since c is a char, equals a char *, so it's going to try to print until the new line character '\0' that is either implicitly or explicitly put in character arrays going to std::cout so the stream knows where the end of the character array is.
So, yeah use the (void *) like 2501 said.