Suppose I have a class like
class A {
int x;
int y;
public:
getSum1() const {
return getx() + y;
}
getSum2() const {
return y + getx();
}
getx() const {
return x;
}
}
And then I have
int main(int argc, char **argv) {
A *a = 0;
switch(argc) {
case 0:
a->getsum1();
break;
default:
开发者_JS百科 a->getsum2();
break;
}
return 1;
}
This program will segfault. I noticed that on my machine, when getsum1 executes, the core dump says the segfault was caused in getx, and when getsum2 executes it says the fault happened in getsum2.
This makes sense. I have 2 questions:
1. is this behaviour specified, or is it implementation dependent? And most importantly: 2. Could the core dump say that the segfault happened in main, when a was dereferenced? (i.e. at a->getsum*)Thanks.
When you called those functions on a null pointer, you got undefined behavior. That's really all that should be said; anything can happen, don't do it.
The reason it segfaults is because there is no A
at null. Attempting to access those members is attempting to access an invalid address. (This happens in getx
and getSum2
, hence the segfault report.)
No, it cannot say the segfault happened in main
because null wasn't accessed in main. (You still entered undefined behavior in main, no doubt, but in practice it just called a function with this
set to null.) You accessed it in those functions. In practice, if a function never uses this
, it won't crash with a null pointer.
But don't.
Calling accessing members and calling member functions on null pointers is undefined behaviour.
The segfault happens when the program tries to access x or y, which is why it happens in getx() in the first one and getSum2() in the second.
By the time the coredump is happening you're not really in C++ anymore. Some statements in the compiled code caused bad things to happen, such as attempting to access an invalid memory address, in your case via a null pointer.
I guess that you're hoping that the diagnostics in the core dump might pin-point the problem rather than (seemingly in this case) giving slightly indeterminate results.
The thing is that going back from compiled binarys to lines of source is somewhat tricky because there's plenbty of scope in the language for some "as-if" kind of reordering of statements and other cleverness.
So, C++ itself, in the language spec, won't specify what the core dump will tell you, and as has already been observed explicitly gives underfined behaviours when de-referencing null pointers.
The thing is I don't really think this matters too much. For this kind of error getting a "close-enough" indictor of where the problem is soon leads to the source of the problem. Far nastier are the heap corruption problems that occur where symptom and cause can be many steps remote from each other and core dumps are less use.
Two important things:
You have undefined behaviour because
a
is null. Undefined behaviour means that anything goes, the C++ standard imposes no restrictions on a program with undefined behaviour.The order of evaluation of the operands to the arithmetic operators is unspecified. That means the compiler may generate code that calls
getX()
first in both of the twogetSum
functions, even though you have ordered them differently. In your particular case the order of evaluation of the operands is consistent.§5/5 “Expressions”: Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified.
"When is the segfault thrown?" Sometimes is never thrown, when should be thrown. Base of most implementation is Operation System with protection of memory. When OS is absent (embedded), or is very simply (CP/M, DOS), or has "low profile" goal (embedded), or CPU haven't such functionality (<80186) problem is hidden or delayed. It is very bad news. Houston, we have BIG invisible problem.
Note: C++ in protected environment can realise scenarios when problem is hidden too (pointer is bad but in valid area)
General rule how to understand C/C++ is key "undefined behaviour" (like many answers say), sometimes such exception
精彩评论