如何解释GDB回溯以确定分段错误?

时间:2018-03-17 23:46:19

标签: c++ debugging segmentation-fault gdb

我在入门级编程课程中。我知道分段错误是由于沿途某处的内存存储错误造成的。我写的程序应该是一个给我们的文件,它在代码中,包含解码它的指令,然后打印解码的消息。

我们有几个测试用例,我的代码运行其中一些,但不是最后一个。今天我第一次了解了GDB的调试问题,并使用了backtrace full来尝试找出错误,但我不完全确定如何解释它给了我什么。

这是我写的代码。 **编辑了代码

当我做回溯时,这就是它告诉我的。

   #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"

我不知道回溯告诉我什么,我不确定如何处理这些信息以发现和修复我的错误。

1 个答案:

答案 0 :(得分:0)

跟踪的提示是

i = 8
chars = ""
numMess = 8

i等于numMesschars为空。

为什么这很重要?查看numMess的来源,我们看到它用于调整msg指向的动态数组的大小,而msg稍后会被i编入索引。当i等于numMess时,msg[i]超出范围。

那是怎么发生的?

string chars;
getline(in, chars); // this doesn't make much sense. Reconsider it
for (chars; std::getline(in, chars); i < numMess) {

这里出了问题。 for循环应该看起来像

for (initializer ; exit condition ; iterator to advance the loop)

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

此处没有任何内容可以阻止i超过numMess,因为i < numMess未被用作退出条件。是的,但为什么当std::getline(in, chars);碰到文件的末尾时,chars没有跳出循环?文件末尾的空行。 for ( ; // nothing happening here i < numMess and std::getline(in, chars) ; ++i) { // and remove the ++i from the end of the loop. 已成功设置为空字符串。

numMess

让你摆脱当前的困境,并可能会给你一个你想要的程序。 Haven没有测试过它。

但是如果文件中有错误并且文件在到达numMess之前退出怎么办?这就是PaulMckenzie所得到的东西。你最好不要完全信任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); } 并且更喜欢

localhost:3000