【问题标题】:Debugging for hours, segmentation fault. Can't find the issue调试了几个小时,分段错误。找不到问题
【发布时间】:2020-03-06 13:48:57
【问题描述】:

有一些似乎可以工作的代码,但突然之间,每次运行代码时我都会遇到分段错误。

希望一双新的眼睛能帮助我找到问题。

它运行这条线 (printf("There are %d arguments excluding (%s)\n", count-1, *(input));) 并在之后崩溃。

我已经尝试使用 gdb 并检查了我的代码,但我似乎找不到问题。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int getDiff(char **list[], int n);
int getSum(char *list[], int n);

int main( int count, char *input[] )
{
    int total;

    printf("There are %d arguments excluding (%s)\n", count-1, *(input));

    if(strcmp(*(input+1),"sum") == 0){
                int i;
        for(i = 2; i<=count;){
            printf("%d ", atoi(*(input + 2)));
            i++;
            if(i < count){
                printf("+ ");
            }
        }
        total = getSum(input, count);
    }


    if(strcmp(*(input+1),"diff") == 0){
        total = getDiff(&input, count);
    }

printf(" === %d ====", total);


}

int getDiff(char **list[], int n){


    int i;
    int total = atoi(**(list + 2));
    for (i=3; i<= n;) {
        int convert;
        convert = atoi(**(list + i));
        total = total - convert;
        i++;
    }

return total;

}

int getSum(char *list[], int n){


    int i;
    int total = atoi(*(list + 2));
    for (i=3; i<= n;) {
        int convert;
        convert = atoi(*(list + i));
        total = total + convert;
        i++;
    }

    return total;

}

应该运行并返回从数字转换而来的整数的总和。

这是 gdb 告诉我的

程序收到信号SIGSEGV,分段错误。 0x00007ffff7b4c196 in __strcmp_sse42 () from /lib64/libc.so.6

【问题讨论】:

  • 当它在 gdb 中崩溃时,堆栈跟踪是什么?你传递的命令行参数是什么?你不检查count 是什么,所以你很容易在input 中越界索引。你可以考虑input[n] 语法。我个人觉得它更容易阅读和理解。
  • @RetiredNinja 我的教授希望我使用指针,我在帖子中添加了 gdb 返回。
  • @chux-ReinstateMonica a.out sum 3 4
  • 好奇的代码使用int getDiff(char **list[], int n){而不是int getDiff(char *list[], int n){。嗯。为什么需要额外的间接级别?
  • gdb 输出中的bt 命令是什么?它应该向您显示代码中导致崩溃的行。

标签: c pointers segmentation-fault coredump


【解决方案1】:

getSum 中的索引需要一些修复。输入list 是 [0-program, 1-"sum", 2-"3", and 3-"4"]。 n = 4。但是,总和外观从 3 变为 4(包括 4)。列表中没有触发 SEGV 的元素 #4。

考虑将循环限制为i&lt;n 而不是i&lt;=n

样式方面,将 i++ 移至“for”语句,声明变量并将它们设置在同一行,并考虑使用索引,而不是指针样式引用(list[i],而不是 *(list+i) . 它将使代码更易于阅读,并有望获得更好的成绩!

int getSum(char *list[], int n){

    int total = atoi(*(list + 2));
    for (int i=3; i< n; i++) {
        int convert = atoi(*(list + i));
        total = total + convert;
    }

    return total;

}

最后,考虑修复变量printf("%d ", atoi(*(input + 2))); 的打印输出。它复制了第二个参数,这不是你想要的。

【讨论】:

  • 啊,我明白了,谢谢。我自己可能不会注意到这一点。干杯!
猜你喜欢
  • 2012-01-22
  • 2017-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多