For this example, we'll use a program that calculates the sum of the numbers entered to it. Download the program's source code sum2.cpp. Once it is downloaded, compile it...
% g++ -o total sum2.cpp
The program should compile without any errors or warnings.
Now, run the executable with some data:
% total Enter numbers to sum below (separated by spaces). Enter 0 (zero) as the last number. 5 6 7 0 Segmentation fault
You'll notice that the program produces a nice Segmentation fault. This calls for using debugging techniques!
Debugging run-time errors can be done by using 2 general techniques:
One way to implement both of these techniques is to use cout
to provide information while the program is running.
cout output may not appear
until endl is printed. In other words, if you don't see
the output of a particular cout statement during run-time,
you can't tell if the program performed that statement, unless
endl was used. If you do use endl, and you
don't see the output, you may conclude the program never got that far.
Alternatively, you can send output to cerr, whose output
is printed immediately (cerr is where error messages are
typically sent).
cout << " is " << sum << endl;
Although both of those produce output, they don't usecout << "The sum of "; PrintValues(values, howmany);
endl,
so we can't tell if the crash occurred before or after them.
That information narrows down the crash some.
To narrow down the location of the problem even more, let's add 2
cout statements. Bring up the code in an editor and add
some debugging statements:
cout << "point A" << endl;
do {
// Read the next number.
cin >> values[howmany];
// Increment the count.
howmany++; // Should error check "howmany"!
} while (values[howmany-1] != 0);
float sum = SumValues(values, howmany);
cout << "The sum of ";
PrintValues(values, howmany);
cout << "point B" << endl;
(Don't forget the endls.)
After editing, save the source code and then recompile the program:
% g++ -o total sum2.cpp
Now, run the executable again:
% total Enter numbers to sum below (separated by spaces). Enter 0 (zero) as the last number. point A 5 6 7 0 Segmentation fault
We see the point A output, but not the one for point B. This confirms our suspicion that the problem is between point A and point B.
Now, we can narrow down the range by moving one (or both) of the
couts. Let's move B above the call to
PrintValues():
cout << "point A" << endl;
do {
// Read the next number.
cin >> values[howmany];
// Increment the count.
howmany++; // Should error check "howmany"!
} while (values[howmany-1] != 0);
float sum = SumValues(values, howmany);
cout << "point B" << endl;
cout << "The sum of ";
PrintValues(values, howmany);
Save this change, recompile, and run the executable again:
% g++ -o total sum2.cpp % total Enter numbers to sum below (separated by spaces). Enter 0 (zero) as the last number. point A 5 6 7 0 Segmentation fault
Again, point A gets printed, but not point B. So, we
know that PrintValues() was not the culprit (else, we'd
see point B before the Segmentation fault!)
Let's move B again...this time above the call to
SumValues():
cout << "point A" << endl;
do {
// Read the next number.
cin >> values[howmany];
// Increment the count.
howmany++; // Should error check "howmany"!
} while (values[howmany-1] != 0);
cout << "point B" << endl;
float sum = SumValues(values, howmany);
Save this change, recompile, and run the executable again:
% g++ -o total sum2.cpp % total Enter numbers to sum below (separated by spaces). Enter 0 (zero) as the last number. point A 5 6 7 0 Segmentation fault
Once more, point A gets printed, but not point B. So, we
know that SumValues() was not the culprit. The problem
must be somewhere in the loop (in main()).
cout << "point A" << endl;
do {
cout << "howmany = " << howmany << endl;
// Read the next number.
cin >> values[howmany];
// Increment the count.
howmany++; // Should error check "howmany"!
} while (values[howmany-1] != 0);
cout << "point B" << endl;
Save this change, recompile, and run the executable again:
% g++ -o total sum2.cpp % total Enter numbers to sum below (separated by spaces). Enter 0 (zero) as the last number. point A howmany = -276903488 ...
Ugh! The index howmany should not be that!
What is the problem?
Go ahead and fix the error. Leave in the debugging output until the program works perfectly (it may still be useful). Save your changes, recompile the program, and run it again.
% g++ -o total sum2.cpp % total Enter numbers to sum below (separated by spaces). Enter 0 (zero) as the last number. point A howmany = 0 5 6 7 0 howmany = 1 howmany = 2 howmany = 3 point B The sum of 5 + 6 + 7 + 0 is 13
The Segmentation fault has been eliminated!! However, now we have a logic error, since the sum should be 18.
Again, we need more information! Suggest a plan for finding the error!!