【问题标题】:An unexplained segmentation fault无法解释的分段错误
【发布时间】:2020-02-04 10:44:14
【问题描述】:

我正在编写代码来反转我输入的每一行中的 char 数组。但是,当我调试程序时,我遇到了分段错误,我不知道为什么。 这是我的代码:

#include <stdio.h>
#define DEFAULT 1000

int reverse(char s[]);

main()
{
    int i;
    char line[DEFAULT] = {'\0'};
    while ((i = getline(line, DEFAULT)) != 0) {
        printf("%s", reverse(line));
    }   
    return 0;
}

/*reverse a line*/
int reverse(char s[])
{
    int i = 0, j = 0;
    while (s[i] != '\n')
        ++i;
    for (j = 0; j < i; ++j) {
        s[2 * i - j] = s[j];
    }
    for (j = 0; j < i; ++j) {
        s[j] = s[j + i + 1];
        s[j + i + 1] = '\0';
    }
    return i;
}

/*get a line from input stream*/
int getline(char s[], int lim)
{
     int i, c, j = 0;
     for (i = 0; ((c = getchar()) != EOF) && (c != '\n'); ++i) {        
        if (i < lim - 2) {
            s[j] = c;   // use j to prevent index out of bounds
            ++j;
        }
     }
     if (c == '\n') {
        s[j] = c;
        ++j;
     }
     s[j] = '\0';
     return i;  // return the length of char s[]
} 

当我输入“abc\n”并执行reverse(s)时,s中的内容变成了“cba\n”,i指的是3,一切正常。当我退出该功能时会发生分段错误。

这里有更多细节:

编译器:GCC 4.9.2 64 位版本

系统:Windows 10

【问题讨论】:

  • s[2 * i - j] 看起来像是越界写给我:i 将是字符串的长度,所以 2*i 不会在 s 数组中。您可能正在覆盖和破坏堆栈上的返回地址。如果你需要临时空间,你将不得不分配一些。 (虽然我想你可能会因为你的数组很大而侥幸逃脱。)但是可以在不需要任何字符串的情况下反转字符串。

标签: c ansi-c


【解决方案1】:

您的函数int reverse(char s[]) 返回一个int,然后您尝试将生成的int 打印为字符串:

printf("%s", reverse(line));

如果您想使用这样的函数,您可以更改其签名以返回char*

char* reverse(char s[]);

然后返回您作为参数提供的s。您的编译器应该发出警告,告知printf 的参数类型错误。如果不是,请尝试将其设置为更严格的警告。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-11
    • 2021-06-26
    • 1970-01-01
    • 2017-12-21
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多