I am in an entry level programming class. I understand that segmentation faults are due to an error in memory storage somewhere along the way. The program I wrote is supposed to take a file given to us that is in code and contains the instructions to decode it and then print the decoded message.
We have several test cases and my code runs for some of them, but not for the last one. I learned about GDB for debugging for the first time today and used backtrace full to try and source the error, but I'm not totally sure how to interpret what it gave me.
This is the code that I wrote. **edited code out
When I did a backtrace, this is what it told me.
#2 0x0000000000401523 in main () at main.cpp:42
second = 61 '='
third = 72 'H'
msg = 0x606308
i = 8
chars = ""
first = 90 'Z'
numMess = 8
out = <incomplete type>
name = "input4.txt"
in = <incomplete type>
arr = "IJKLMNOPQRSTUVWXYZABCDEFGH"
I don't know what the backtrace is telling me and I'm unsure of what to do with that information to discover and fix my error.
The hints from the trace are
i = 8
chars = ""
numMess = 8
i
equals numMess
and chars
is empty.
Why does this matter? Looking at where numMess
comes from, we see it's used to size the dynamic array pointed at by msg
and msg
is later indexed by i
. when i
equals numMess
, msg[i]
is out of bounds.
So how did this happen?
string chars;
getline(in, chars); // this doesn't make much sense. Reconsider it
for (chars; std::getline(in, chars); i < numMess) {
Here's where things went wrong. A for loop should look something like
for (initializer ; exit condition ; iterator to advance the loop)
but
for (chars; // does nothing. Compiler may be warning you
std::getline(in, chars); // loop exits on failed read
i < numMess) { // does nothing to advance the loop
Nothing in here prevents i
from exceeding numMess
because i < numMess
is not being used as an exit condition. Right, but why doesn't std::getline(in, chars);
kick out of the loop when it hits the end of the file? Empty line at the end of the file. chars
was successfully set to an empty string.
for ( ; // nothing happening here
i < numMess and std::getline(in, chars) ;
++i) { // and remove the ++i from the end of the loop.
Gets you out of the current predicament and might give you a program that does what you want. Haven't tested it.
But what if there is a mistake in the file and the file exits before reaching numMess
? This is the sort of stuff PaulMckenzie is getting at. You're better off not trusting numMess
at all and going with something more like
int numMess = 0;
in >> numMess; // not that we care
vector<Messages> msg;
//read file
int i = 0;
string chars;
while (std::getline(in, chars)) { // get each line. Note this gets the empty line, too
Messages temp; // make a temporary for storage
temp.messageNum = i + 1;
temp.codedMessage = chars;
//decode file
for (char &j : chars) {
if (j - 'A' >= 0 && j - 'A' < 26)
j = arr[j - 'A'];
}
temp.decodedMessage = chars;
msg.push_back(temp);
}
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.