I have the following C++ code. I am asking for a memory value from a NULL pointer. I mean, I am doing something like NULL-> kind of operation. I know this is an error . I am doing this operation inside the function 'funct' and I am printing the word Before Error before calling this function. As the program runs, this message must be printed and then the error must happen. Instead, directly the error happens. Why is it so?
Is it because the print statement and funct execution are independent and so they happen in different threads/cores and so the error precedes the printing ?
#include <iostream>
#include <string>
using namespace std;
struct A
{
int a;
};
void funct(int a)
{
A *obj;
obj = NULL;
cout<<"Value is "<<obj->a;
}
int main()
{
cout<<"Before Error";
funct(205);
getchar();
cout<<"\n END \n";
}
This is happening because cout
output is buffered by default. Your program is getting a segmentation fault before it has a chance to flush the output buffer. You can disable buffering with this:
std::cout.setf(std::ios::unitbuf);
If you put that at the top of main()
, you'll see the output before the segfault message. There are performance implications why you might not want to disable buffering, but in this case it'll show that the message really is being written.
You can also do a one-time flush of the buffer:
cout<<"Before Error";
std::cout.flush();
funct(205);
Dereferencing a null pointer is undefined behavior.
The behavior of your program is entirely undefined.
The compiler can, and will, do some crazy things when you have undefined behavior.
Reasoning about a program with undefined behavior is a futile effort.
That being said, you might want to ad a << endl
to every time you call cout
, as this will flush the buffer to stdout. This may (or may not, entirely dependent on the compiler and the optimizations being done!) have some type of impact on the behavior of your program. But this is just guessing. It might not even do what you want. It might make random information be sent to stdout. Reasoning about undefined behavior is very difficult.
For example, exploring your code on the assembly level with -O3
on GCC 6.2, the string '\\n END \\n' is not at all in the assembly (relevant but not complete assembly reproduced below).
funct(int):
mov eax, DWORD PTR ds:0
ud2
.LC0:
.string "Before Error"
main:
mov edi, OFFSET FLAT:std::cout
sub rsp, 8
mov esi, OFFSET FLAT:.LC0
call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
mov edi, 205
call funct(int)
sub rsp, 8
mov edi, OFFSET FLAT:std::__ioinit
call std::ios_base::Init::Init()
mov edx, OFFSET FLAT:__dso_handle
mov esi, OFFSET FLAT:std::__ioinit
mov edi, OFFSET FLAT:std::ios_base::Init::~Init()
add rsp, 8
jmp __cxa_atexit
Behaviour could differ based on platform (linux or windows) and compiler settings. On linux, printf/cout doesn't lead to immediate display after execution of statement. you may want to explicitly flush by using std::cout.flush(); or put the endl.
In fact, the message has been printed, you can check by using:
cout << "Before Error";
Sleep(5000);
funct(205);
After 5s, the error will be caught.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.