Null pointer to cout

R

Ralf Goertz

Hi,

this might be intentional, but I don't see a reason, why.

Running the program
----------------------
#include <iostream>
using namespace std;

int main(){
char *x=NULL;
cout<<"before"<<endl;
cout<<x<<endl;
cout<<"after"<<endl;
}
-------------------------

I would expect to see

-------------
before

after
-------------

but instead I get only

------------
before
------------

The program exits normally. Is that behaviour correct or is it a bug?

Linux i386, gcc version 4.0.2 20050901 (prerelease) (SUSE Linux)

Thanks,

Ralf
 
P

peter koch

Ralf said:
Hi,

this might be intentional, but I don't see a reason, why.

Running the program
----------------------
#include <iostream>
using namespace std;

int main(){
char *x=NULL;

This is not the empty string. For that you should have char *x="";
cout<<"before"<<endl;
cout<<x<<endl;
Here you try to cout something that does not exist.
cout<<"after"<<endl;
}

That is correct behaviour. Null-pointers never denote the empty string.

/Peter
 
A

amirkam1

"Here you try to cout something that does not exist. "

But I do not understand why the third cout printing after does not work
?

I have observed a similar behaviour with CIN
int a;
cin>>a;

int b;
cin>>b;

cout<<b;
Now if the first input to the program is given as a string the second
cin, does not come into picture at all.
Some garbage gets printed as b remains uninitialised.


regards,
Amir Kamerkar
 
T

Tomás

Ralf Goertz posted:
Hi,

this might be intentional, but I don't see a reason, why.

Running the program
----------------------
#include <iostream>
using namespace std;

int main(){
char *x=NULL;


The pointer "x" now contains the following memory address:

0x00000000

(Note to nit-pickers: Yes I realise that it needn't be all-bits-zero.)

cout<<"before"<<endl;

Here you print "before".
cout<<x<<endl;


Here you're forcing the computer to read from the memory location:
0x00000000


The C++ Standard says that this is Undefined Behaviour.

cout<<"after"<<endl;


You've already gone messing around with invalid memory, so your program's
already messed up.


-Tomás
 
R

Ralf Goertz

Tomás said:
Here you're forcing the computer to read from the memory location:
0x00000000


The C++ Standard says that this is Undefined Behaviour.




You've already gone messing around with invalid memory, so your program's
already messed up.

Okay, that I can understand. It took me quite a while to find this problem
at
all because I actually used a QString variable str and didn't know that in
my
particular case str.isNull() could ever be true. I would have found the
problem faster if the problem had segfaulted. Why didn't it if it actually
messed around with invalid memory?

Ralf
 
T

Tomás

Ralf Goertz posted:
I would have found
the problem faster if the problem had segfaulted. Why didn't it if it
actually messed around with invalid memory?


Write an e-mail to your operating system's manufacturer and they might tell
you -- because Standard C++ certainly says that all bets are off once you
start messing with null pointers.

However, on your particular platform, it may be perfectly okay to mess with
a null pointer, and it may have absolutely no effect:

int *p = 0;

*p = 5; /* No effect */


Then again, your operating system just might not be complaining about
memory being messed around with.


-Tomás
 
A

Alan Johnson

Ralf said:
I would have found the problem faster if the problem had segfaulted. Why
didn't it if it actually messed around with invalid memory?

That's the thing about undefined behavior, it is undefined. It could
mean segfaulting, or it could mean doing any other arbitrary thing.

It is my guess that your implementation sets the failbit for cout when
you try to insert a NULL pointer. You can force an exception to be
thrown when that happens by calling:
cout.exceptions(ios_base::failbit) ;

Not exactly a segfault, but it will still get your attention.
 
C

C. Benson Manica

Here you're forcing the computer to read from the memory location:
0x00000000

Is there no built-in equivalent to the %p printf() format specifier?
 
J

Jonathan Mcdougall

C. Benson Manica said:
Is there no built-in equivalent to the %p printf() format specifier?

Yes:

void f(char* s)
{
std::cout << static_cast<void*>(s);
}

operator<< for std::eek:stream is overloaded for the char* family; these
are being interpreted as c-style strings.


Jonathan
 
C

Christopher Benson-Manica

Jonathan Mcdougall said:
void f(char* s)
{
std::cout << static_cast<void*>(s);
}
operator<< for std::eek:stream is overloaded for the char* family; these
are being interpreted as c-style strings.

If s is NULL, is that defined?
 
P

peter koch

Christopher Benson-Manica skrev:
If s is NULL, is that defined?

That depends on what you mean with your question. For the function
shown, the output is well-defined also if s is null. For the
overloaded operator in in char* family, the output is NOT defined for a
null-pointer - exactly as was demonstrated by the first post.

/Peter
 
C

C. Benson Manica

peter said:
That depends on what you mean with your question. For the function
shown, the output is well-defined also if s is null. For the
overloaded operator in in char* family, the output is NOT defined for a
null-pointer - exactly as was demonstrated by the first post.

Well, since AFAIK

printf( "Pointer=%p\n", static_cast<void*>(some_pointer) );

is valid even if some_pointer is NULL, it seems that there is indeed no
builtin way to print a null pointer to std::cout...
 
J

Jonathan Mcdougall

C. Benson Manica said:
Well, since AFAIK

printf( "Pointer=%p\n", static_cast<void*>(some_pointer) );

is valid even if some_pointer is NULL, it seems that there is indeed no
builtin way to print a null pointer to std::cout...

Either your don't understand the answers or we don't understand the
question.

void f(char* s)
{
// ok if s points to a valid c-style string
// undefined behavior if s==0
std::cout << s;

// always valid, outputs the pointer value
std::cout << static_cast<void*>(s);
}


Jonathan
 
C

C. Benson Manica

Jonathan said:
Either your don't understand the answers or we don't understand the
question.

Well, you're the first to understand it...
// always valid, outputs the pointer value
std::cout << static_cast<void*>(s);

....since that's what I was aiming at. Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top