【问题标题】:How to fix 'Segmentation Fault (core dumped)' error如何修复“分段错误(核心转储)”错误
【发布时间】:2019-07-18 20:13:40
【问题描述】:

我刚刚开始学习一些 C 语言,所以我编写了一个小程序来练习使用 char 数组。 它从stdin 中获取一个字符串,并在删除尾随空格和空行后打印它(如果你们中的任何人有“C 编程语言”的第二版,那就是问题 1-18)。 然而,在按下 EOF 键结束输入后,程序退出并出现错误:'Segmentation fault (core dumped)'。

我已经使用WallWextraWerrorg 进行了编译,但在编译时没有显示错误(在 Fedora 30 上使用 gcc 9.1.1)。 我也通过gdb运行程序,发现导致故障的行是这一行:

for (; (c = input[start + i]) != '\n' || c != '\0'; ++i)

我正在粘贴整个文件,因为它是一个简短的程序,一切都可能是导致错误的原因。

#include <stdio.h>

#define MAX 100

int Read(char input[], int max);
void ProcessInput(char input[], char output[], int length);
int GetToEndLine(char input[], char outLine[], int startIndex);

int main(void){
    char input[MAX];
    char output[MAX];
    int length;
    printf("W: Max output is of %d chars.\n", MAX - 1);
    length = Read(input, MAX);
    ProcessInput(input, output, length);
    printf("\nCleaned input:\n---\n%s\n---\n", output);
    return 0;
}

int Read(char input[], int max){
    int i, c;
    for (i = 0; (c = getchar()) != EOF && i < max - 1; ++i)
        input[i] = c;
    input[i] = '\0';
    return i;
}

void ProcessInput(char input[], char output[], int length){
    int mainIndex = 0,
        new_mainIndex = 0,
        outputIndex = 0;
    char line[MAX];
    while ((length - mainIndex) > 0){
        new_mainIndex = GetToEndLine(input, line, mainIndex);
        if (new_mainIndex == mainIndex){
            ++mainIndex;
            continue;
        }
        for (int j = new_mainIndex - mainIndex; 
                line[j] == ' ' || line[j] == '\t' || line[j] != '\n'; --j)
            line[j] = '\0';
        for(int j = 0; line[j] != '\0'; ++j, ++outputIndex)
            output[outputIndex] = line[j];
        output[outputIndex] = '\n';
        ++outputIndex;
        mainIndex = new_mainIndex + 1;
    }
}

int GetToEndLine(char input[], char line[], int start){
    int c, 
        i = 0;
    for (; (c = input[start + i]) != '\n' || c != '\0'; ++i)
        line[i] = c;
    line[i] = c;
    return start + i;
}

成功的测试运行的完整输出应该是:

W: Max output is of 99 chars.
asdf   

asdf
Cleaned Input:
---
asdf
asdf
---

我得到的是:

W: Max output is of 99 chars.
asdf   

asdfSegmentation fault(core dumped)

有人可以帮我调试这个程序吗?

【问题讨论】:

  • 崩溃发生时,所有涉及的变量的值是多少?他们看起来神志清醒吗?没有越界索引?
  • 我不知道段错误,但表达式 a != X || a !=Y 对每个不相等的 XY 都是正确的
  • @EugeneSh。我认为你在那里做了一些事情,for 循环需要是 && 而不是 ||。连续循环可能是段错误,因此当它超过输入+1的长度时,给他一个超出范围的索引。
  • 建议使用strchrnul(str, '\n');
  • @plum0 我一点也不困惑。我正在确认您的“可能”是“最肯定是”。我也不会说这是唯一的问题,但那绝对会导致无限循环,最终会破坏该数组并调用 UB。

标签: c arrays char


【解决方案1】:

GetToEndLine() 似乎会继续循环,直到内存不足。您的意思是使用逻辑和而不是逻辑或吗?试试for (; (c = input[start + i]) != '\n' &amp;&amp; c != '\0'; ++i)

int GetToEndLine(char input[], char line[], int start) {
    int c,
        i = 0;
    for (; (c = input[start + i]) != '\n' && c != '\0'; ++i)
        line[i] = c;
    line[i] = c; // What is the purpose of this?
    return start + i;
}

这应该可以解决您的直接段错误问题。

【讨论】:

  • 修复了第一个段错误。然后在 ProcessInput 中的一个 for 循环中弹出另一个,但那是因为输入错误并将 != 更改为 == 修复了它。关于冗余赋值的问题,我把它放进去,否则最后一个'\n'将不会被包含在内,导致其他函数打印垃圾。
猜你喜欢
  • 2021-06-23
  • 2016-03-13
  • 1970-01-01
  • 2014-08-04
  • 2012-11-19
  • 1970-01-01
  • 2019-03-14
  • 2017-04-05
  • 2019-09-03
相关资源
最近更新 更多