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

使用stdlib.c的qsort()按字符串第3位数字排序触发SIGSEGV错误排查

问题分析与解决方案

你的段错误问题确实出在类型转换和qsort参数的错误上,还有一个容易忽略的下标问题,我帮你拆解清楚:

核心错误点

1. qsort的元素大小参数错误

你调用qsort时传了sizeof(char),但你的数组string_mix是char*类型的数组(每个元素是指向字符串的指针),单个元素的大小应该是sizeof(char*)(通常是4或8字节,取决于平台)。传sizeof(char)会让qsort以1字节为步长遍历数组,完全错误地访问内存,直接导致非法内存访问。

2. 对比函数的类型转换错误

qsort传给对比函数的a和b参数,是指向数组元素的指针——也就是说,你的数组元素是char*,那么a和b的实际类型是char**。你直接把void*转成const char*,相当于把指针的内存地址当成了字符串的首地址去访问,这必然会触发段错误。

3. 字符串下标错误

你提到每个字符串的第3位是数字,但C语言的字符串下标是从0开始计数的:第1位是[0],第2位是[1],第3位是[2]。原来的代码用ia[3]取的是第4个字符,这会导致你比较的不是预期的数字,即使没崩溃,排序结果也不对。

修正后的代码

修正qsort调用

qsort(string_mix, (size_t)(k - 1), sizeof(char*), compare_at3);

修正对比函数

int compare_at3(const void* a, const void* b){
    static int k = 1;
    // 先把void*转成指向char*的指针,再解引用拿到字符串指针
    const char *ia = *(const char**)a;
    const char *ib = *(const char**)b;
    printf("In compare_at3 %d iter\n", k++);
    // 取第3位(下标2)的数字进行比较
    int num_a = ia[2] - '0';
    int num_b = ib[2] - '0';
    return num_a - num_b;
}

验证示例

我写了一个完整的可运行示例,你可以参考:

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

#define MAX_NO_OF_STRINGS 10

int compare_at3(const void* a, const void* b){
    static int k = 1;
    const char *ia = *(const char**)a;
    const char *ib = *(const char**)b;
    printf("In compare_at3 %d iter\n", k++);
    int num_a = ia[2] - '0';
    int num_b = ib[2] - '0';
    return num_a - num_b;
}

int main() {
    char* string_mix[MAX_NO_OF_STRINGS] = {"aob3l", "gou5!", "oib1k", "llp6d"};
    int k = 5; // 假设k-1是数组中有效元素的数量

    qsort(string_mix, (size_t)(k - 1), sizeof(char*), compare_at3);

    // 打印排序结果
    for (int i = 0; i < k-1; i++) {
        printf("%s ", string_mix[i]);
    }
    printf("\n");
    return 0;
}

运行这段代码会输出你预期的结果:oib1k aob3l gou5! llp6d,而且不会触发段错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:30:43