This question already has answers here:
Unable to print the value of nullptr on screen
(3 answers)
Closed 2 years ago.
I wonder about "cout" nullptr doesn't work.
It work only once.
But "printf" work on the main function.
#include <iostream>
int main() {
const char *np=nullptr;
std::cout << "np: "<<np<<std::endl;
std::cout << "np: "<<np<<std::endl;
std::cout << "np: "<<np<<std::endl;
printf("printf np:%s\n",np);
std::cout << "np: "<<np<<std::endl;
std::cout << "np: "<<np<<std::endl;
}
It work like below.
np: printf np:(null)
It's undefined behaviour
In both cases you are printing a C-style-string (a const char *). So the implementation needs to find the length of this string and searches the terminating null character in it. But the pointer is invalid, so you get undefined behaviour.
Technically both cases are UB, but the implementation of printf you are using seems to be recognizing the invalid pointer and prints (null) instead, whereas std::cout just crashes.
(Or maybe it also recognizes the invalid pointer and gracefully sets the fail bit, thus ignoring further operations. But ultimately it's UB, so anything can happen here.)
nullptr is a type of std::nullptr_t, which doesn't defines the any operators for std::cout to be able print objects of that type.
One possible way to print, it'll print zero although:
#include <iostream>
int main(void) {
const char *np = nullptr;
std::cout << static_cast<const void*>(np) << std::endl;
return 0;
}
Just cast it to a const void pointer. Then you'll get something like:
0
But not (null), this is what was explained in the top.
Related
This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Closed 5 years ago.
char p;
cout << &p;
This does not print the address of character p. It prints some characters. Why?
char p;
char *q;
q = &p;
cout << q;
Even this does not. Why?
I believe the << operator recognizes it as a string. Casting it to a void* should work:
cout << (void*)&p;
std::basic_ostream has a specialized operator that takes a std::basic_streambuf (which basically is a string (in this case)):
_Myt& operator<<(_Mysb *_Strbuf)
as opposed to the operator that takes any pointer (except char* of course):
_Myt& operator<<(const void *_Val)
This is because the pointer to char has its own overload of <<, which interprets the pointer as a C string.
You can fix your code by adding a cast to void*, which is the overload that prints a pointer:
char p;
cout << (void*)&p << endl;
Demo 1.
Note that the problem happens for char pointer, but not for other kinds of pointers. Say, if you use int instead of char in your declaration, your code would work without a cast:
int p;
cout << &p << endl;
Demo 2.
std::cout will treat a char* as a string. You are basically seeing whatever is contained in memory at the location of your uninitialised pointer - until a terminating null character is encountered. Casting the pointer to a void* should print the actual pointer value if you need to see it
This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Printing C++ int pointer vs char pointer
(3 answers)
Closed 4 years ago.
Keep in mind that my knowledge of pointers is quite small, as I just started learning about them.
While I was messing around in C++, I wrote this small bit of code thinking it would just print out the address of each character in the string
#include <iostream>
using namespace std;
string a = "Hello, World!";
int main() {
for(int i=0; i<a.length();i++) {
cout << &a[i] << endl;
}
return 0;
}
When I compiled and ran this, however, it resulted in it printing as if the string moved to the left.
It just doesn't make sense why when it uses &, which I thought would retrieve the address, would instead get the rest of the string.
As said in the comment, &a[i] is a pointer to a char, and << operator will print null terminated string starting from this character, not its address. So if you want to print the address, you must cast it to void *, as follow :
#include <iostream>
using namespace std;
string a = "Hello, World!";
int main() {
for(int i=0; i<a.length();i++) {
cout << (void *)&a[i] << endl; //cast to (void *) to get the address
}
return 0;
}
string subscript ([]) operator returns char. So & operation returns a pointer to char. And cout operator<< has an overloading for it, which consider it should print out the parameter as a c-string. You should cast it to void* so cout wouldn't think it is a string.
(void*)&a[i]
I'm looking at the macro offsetof from <cstddef>, and saw that a possible implementation is via
#define my_offsetof(type, member) ((void*) &(((type*)nullptr)->member))
I tried it and indeed it works as expected
#include <iostream>
#define my_offsetof(type, member) ((void*) &(((type*)nullptr)->member))
struct S
{
char x;
short y;
int z;
};
int main()
{
std::cout << my_offsetof(S, x) << '\n';
std::cout << my_offsetof(S, y) << '\n';
std::cout << my_offsetof(S, z) << '\n';
S s;
std::cout << (void*) &((&s)->x) << '\n'; // no more relative offsets
std::cout << (void*) &((&s)->y) << '\n'; // no more relative offsets
std::cout << (void*) &((&s)->z) << '\n'; // no more relative offsets
}
Live on Coliru
the only modification I've done being that I use a final cast to void* instead of size_t, as I want to display the address as a pointer.
My question(s):
Is the code perfectly legal, i.e. is it legal to "access" a member via a nullptr, then take its address? If that's the case, then it seems that &(((type*)nullptr)->member) computes the address of the member relative to 0, is this indeed the case? (it seems so, as in the last 3 lines I get the offsets relative to the address of s).
If I remove the final cast to (void*) from the macro definition, I get a segfault. Why? Shouldn't &(((type*)nullptr)->member) be a pointer of type type*, or is the type somehow erased here?
Is the code perfectly legal?
No. It's undefined behavior. A compiler may choose to implement offsetof in that manner, but that's because it is the implementation: it can choose how to implement its own features. You, on the other hand, do not get such "luxury."
There is no way for you to implement the offsetof macro. Not in any standards-conforming manner.
If I remove the final cast to (void*) from the macro definition, I get a segfault. Why? Shouldn't &(((type*)nullptr)->member) be a pointer of type type*, or is the type somehow erased here?
It's probably a segfault from trying to print my_offsetof(S, x) (since x is a char and that expression results in char*), because std::ostream's operator<< will try to print char* as a C-style string.
This question already has answers here:
Why does std::cout output disappear completely after NULL is sent to it
(3 answers)
Closed 8 years ago.
I'm learning about pointers in C++. I wrote this simple program to show what I had a problem with:
#include <iostream>
using namespace std;
int main() {
cout << "test1";
char *ptr = 0;
cout << ptr;
cout << "test2";
}
When I run the program, it doesn't output "test2" at the end, instead only "test1". This should mean that it crashed when I tried to print out the value of ptr? I tried stepping through it in Eclipse debugger and it looks like every line gets executed but doesn't it throw an error or something?
char *ptr = 0;
cout << ptr;
There's an overload of the << operator that takes a char* operand, which it assumes is a pointer to a C-style string.
For pointer types other than char*, the << operator would print the value of the pointer (which is an address), but treating a null char* pointer as if it pointed to a C-style string causes undefined behavior. In any case, it's not going to print the pointer value.
To print the pointer value, you can convert it to void*:
cout << "test1\n";
char *ptr = 0;
cout << static_cast<void*>(ptr) << "\n";
cout << "test2" << "\n";;
Normally you can output a pointer to cout and it will print the address contained. However, when you output a char * it is interpreted as a C-style null-terminated string. In this case, it's a null pointer and does not point to a string.
Try casting it to a void * before outputting it.
This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Closed 5 years ago.
Why does
#include <iostream>
using namespace std;
int main() {
cout << (char*)0x10 << endl;
}
segfault, but
#include <iostream>
using namespace std;
int main() {
cout << (void*)0x10 << endl;
}
seems to work just fine?
Because
cout::operator <<(void*)
prints a memory address, and
cout::operator <<(char*)
prints a null-terminated character array, and you run into undefined behaviour when you attempt to read the char array from 0x10.
The ostream::operator<< is overloaded, there is a version for char* which interprets the given pointer as a null-terminated string.
There's a special overload for << with char*, so that C-style strings can be output easily.
Thus
cout << (char*)0x10 << endl;
tries to print out the string located at (char*)0x10 which is not memory it's supposed to look at.