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

qsort排序无符号长整型数组时被填充为全零的问题排查

解决qsort排序unsigned long数组时被填充为零的问题

看起来你在使用qsort排序unsigned long数组时踩了两个关键的坑,这直接导致了数组被意外覆盖为零。咱们一步步拆解问题和修复方案:

1. qsort参数传递的致命错误

首先得明确qsort的参数要求,它的函数签名是:

void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *))

这里的第二个参数nmemb是数组的元素个数,而不是数组的总字节数!但你的调用里:

qsort(scores[c], sizeof(scores[c]), sizeof(scores[c][0]), comparator);

把sizeof(scores[c])(整个数组行的总字节数)传给了nmemb,这会让qsort误以为数组有这么多个元素——比如如果scores[c]有5个unsigned long元素,sizeof(scores[c])就是5*8=40(假设long是8字节),qsort会试图处理40个元素,远远超出数组实际长度,直接造成内存越界访问,最终把你的数组覆盖成零(或者其他随机垃圾值)。

修正后的调用方式

你需要把第二个参数改成实际的元素个数:

  • 如果是固定长度的二维数组,比如unsigned long scores[10][20],那第c行的元素个数就是20:
    qsort(scores[c], 20, sizeof(scores[c][0]), comparator);
    
  • 如果想动态计算元素个数(更通用),可以用总字节数除以单个元素的字节数:
    size_t elem_num = sizeof(scores[c]) / sizeof(scores[c][0]);
    qsort(scores[c], elem_num, sizeof(scores[c][0]), comparator);
    

2. 比较器的unsigned类型适配问题

从你给出的比较器片段来看,需要注意unsigned long的比较逻辑不能直接用减法返回结果。比如如果写return *(unsigned long*)p - *(unsigned long*)q,当左边的值小于右边时,因为是无符号类型,差值会溢出成一个很大的正数,qsort会错误地认为左边的值更大,导致排序逻辑完全混乱。

正确的比较器实现应该是:

int comparator(const void *p, const void *q) {
    const unsigned long val_a = *(const unsigned long *)p;
    const unsigned long val_b = *(const unsigned long *)q;

    if (val_a < val_b) {
        return -1; // 表示val_a应该排在val_b前面
    } else if (val_a > val_b) {
        return 1;  // 表示val_a应该排在val_b后面
    }
    return 0; // 两个值相等
}

3. GDB调试的验证点

你可以在GDB里做这些操作来确认修复效果:

  • 调用qsort之前,用print scores[c]打印数组初始值,确认数据是正确的
  • 计算并打印elem_num的值,检查是否等于数组实际的元素个数
  • 单步跟踪qsort的执行,观察内存访问是否在合法范围内

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:28:46