使用C语言qsort排序ProcArray时触发段错误的排查求助
问题描述
我编写了用于排序比较的compareByMemSize函数,用来对ProcInfo结构体数组按内存大小排序,但调用qsort后触发了段错误。相关代码如下:
比较函数compareByMemSize
int compareByMemSize(const void *a, const void *b) { const struct ProcInfo *procInfo1 = (const struct ProcInfo *) a; const struct ProcInfo *procInfo2 = (const struct ProcInfo *) b; if (( procInfo1->memSize != NULL && procInfo1->memSize[0] != '\0' ) && ( procInfo2->memSize != NULL && procInfo2->memSize[0] != '\0' )) { long memSize1 = strtol(procInfo1->memSize, NULL, 10); long memSize2 = strtol(procInfo2->memSize, NULL, 10); if (memSize1 < memSize2) return -1; if (memSize1 > memSize2) return 1; return 0; } if (procInfo1->memSize == NULL && procInfo2->memSize == NULL) return 0; if (procInfo1->memSize == NULL) return -1; return 1; }
相关结构体定义
ProcInfo结构体
typedef struct ProcInfo { int PID; char *name; char *memSize; } ProcInfo;
ProcArray结构体
typedef struct ProcArray { ProcInfo *array; size_t used; size_t size; } ProcArray;
qsort调用代码
qsort(&a, sizeof(a), sizeof(ProcInfo), compareByMemSize);
其中a是ProcArray类型变量。我猜测段错误可能和memSize的取值有关:它可能是类似"122313131"的长数字字符串(已去除原有的"kB"后缀),也可能是空字符'\0';部分不存在的memSize我已设为'\0',并在比较函数中做了判断。想请教是qsort使用有误,还是memSize的处理方式有问题?如需更多代码可提供!
问题分析与解决
1. qsort调用的核心错误
你的qsort调用存在两个致命错误,这是触发段错误的直接原因:
- 第一个参数错误:
qsort要求传入待排序数组的起始地址,你传入的&a是ProcArray结构体本身的地址,但实际要排序的是a.array指向的ProcInfo数组。 - 第二个参数错误:
qsort的第二个参数是数组中元素的数量,你传入的sizeof(a)是ProcArray结构体的字节大小,正确值应该是a.used(数组中已实际存储的元素个数)。
修正后的qsort调用代码:
qsort(a.array, a.used, sizeof(ProcInfo), compareByMemSize);
2. memSize处理的潜在问题
虽然当前段错误不是由memSize处理导致,但这部分逻辑有几个可优化的点:
- 当前判断
memSize[0] != '\0'前先检查了memSize != NULL,这部分是安全的,不会出现空指针解引用。 strtol转换无效字符串时会返回0,比如memSize是乱码的情况,会被当作0处理。如果需要区分"有效0值"和"转换失败",可以通过strtol的第二个参数(endptr)验证:char *endptr; long memSize1 = strtol(procInfo1->memSize, &endptr, 10); if (*endptr != '\0') { // 转换失败,可根据需求自定义处理逻辑,比如将这类元素排到末尾 }- 当前排序规则会把
memSize为NULL或空字符串的元素排在前面,如果这不符合你的预期,需要调整返回值逻辑(比如返回1让这类元素排到后面)。
内容的提问来源于stack exchange,提问作者Mathew
相关产品推荐
相关产品推荐

