You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复‘segmentation fault (core dumped)’错误?程序排序正常却终报错

修复C程序排序终端参数后的段错误问题

我写的C程序可以按ASCII顺序排序并打印终端传入的参数,功能符合预期,但运行结束时会出现segmentation fault (core dumped)错误。已知这是非法内存访问问题,但不知道怎么修复。这是学校作业,仅允许使用write函数。

我的代码如下:

#include<unistd.h>

int     c_strcmp(char *str1, char *str2)
{
        int     i;

        i = 0;
        while (str1[i] || str2[i])
        {
                if (str1[i] > str2[i])
                        return (1);
                if (str1[i] < str2[i])
                        return (-1);
                i++;
        }
        return (0);
}

void    c_putstr(char *str)
{
        int     i;

        i = 0;
        while (str[i])
        {
                write(1, &str[i], 1);
                i++;
        }
        write(1, "\n", 1);
}

int     main(int argc, char *argv[])
{
        int     i;
        char    *temp;

        i = 1;
        while (i < (argc - 1))
        {
                if (c_strcmp(argv[i], argv[i + 1]) > 0)
                {
                        temp = argv[i];
                        argv[i] = argv[i + 1];
                        argv[i + 1] = temp;
                        i = 0;
                }
                i++;
        }
        i = 0;
        while (i < argc)
        {
                i++;
                c_putstr(argv[i]);
        }
}

运行输出示例:

a2-r2-p8% ./a.out test2 test3 test1 test4 | cat -e
test1
test2
test3
test4
zsh: segmentation fault (core dumped)  ./a.out test2 test3 test1 test4 | 
zsh: done                              cat -e
a2-r2-p8% ./a.out abg b cdf abc z azz | cat -e
abc
abg
azz
b
cdf
z
zsh: segmentation fault (core dumped)  ./a.out abg b cdf abc z azz | 
zsh: done                              cat -e

程序能正确排序打印,但最终仍报错,请问该如何修复?


问题原因与修复方案

段错误的根源是打印循环越界访问了argv[argc]:

  • C标准规定,argv数组的最后一个元素argv[argc]是NULL指针
  • 你的打印循环逻辑是:i从0开始,当i < argc时,先i++再调用c_putstr(argv[i])。当i = argc-1时,i++后变成argc,此时argv[argc]是NULL,传入c_putstr后,函数里的while(str[i])会尝试访问NULL指向的内存,直接触发段错误。

修复后的main函数

调整打印循环的起始值和逻辑,只遍历需要打印的argv[1]到argv[argc-1]:

int     main(int argc, char *argv[])
{
        int     i;
        char    *temp;

        i = 1;
        while (i < (argc - 1))
        {
                if (c_strcmp(argv[i], argv[i + 1]) > 0)
                {
                        temp = argv[i];
                        argv[i] = argv[i + 1];
                        argv[i + 1] = temp;
                        i = 1; // 这里改成1比0更合理,避免重复检查程序名argv[0]
                }
                i++;
        }
        // 修复打印循环:从i=1开始,遍历到argc-1
        i = 1;
        while (i < argc)
        {
                c_putstr(argv[i]);
                i++;
        }
}

额外说明

排序逻辑里的i = 0改成i = 1是优化项——因为argv[0]是程序名,不需要参与排序,从1开始重新检查能减少不必要的循环次数,不影响最终排序结果。


内容的提问来源于stack exchange,提问作者brmajor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 01:55:18