K&R C 5.11函数指针排序程序输入首行后崩溃求助
K&R C排序程序崩溃问题排查
问题场景
实现《C程序设计语言》(K&R)第120页函数指针章节的排序程序,支持-n参数进行数值排序,默认按字典序排序,但输入首行后程序崩溃。gdb调试显示崩溃触发于strcmp函数,产生SIGSEGV段错误,怀疑readlines函数的内存管理存在问题。
核心排查方向
1. 内存分配有效性校验
检查readlines中malloc/realloc的返回值,若内存分配失败返回NULL,后续直接操作该指针会触发段错误。必须在分配后立即校验:
char *p = malloc(len); if (p == NULL) { // 释放已分配的内存资源,返回错误标记 return -1; }
2. 行指针数组的边界检查
确认存储行指针的数组(如char *lineptr[])是否有足够容量,若输入行数超过数组上限,会导致指针数组越界,覆盖其他内存区域,后续strcmp访问非法地址。需在添加行前检查当前行数是否小于数组最大容量:
if (nlines >= maxlines) { // 行数超出上限,返回错误 return -1; }
3. strcmp传入指针的合法性
崩溃发生在strcmp,说明至少有一个传入指针是无效值(NULL或野指针)。检查readlines的逻辑:
- 是否在读取行后,未正确将分配的内存指针赋值给
lineptr[nlines]就递增了索引 - 是否内存分配后,未复制行内容就存储了未初始化的指针
- 是否处理输入异常(如空行、EOF)时,错误地向
lineptr中存入了NULL指针,且排序逻辑未处理该情况
4. 输入行的终止符处理
确认readlines是否正确处理换行符,比如将读取到的换行符替换为字符串终止符\0,否则行内容会包含非法字符,导致strcmp访问超出内存块的区域:
line[len-1] = '\0'; // 替换换行符为终止符 strcpy(p, line);
5. 排序函数的参数合法性
如果使用书中自定义的qsort函数,检查传入的元素数量是否正确。若元素数量错误,排序函数会访问超出lineptr范围的指针,进而在调用比较函数时触发崩溃。
示例修复代码片段
修复后的readlines函数
#define MAXLEN 1000 int readlines(char *lineptr[], int maxlines) { int len, nlines; char *p, line[MAXLEN]; nlines = 0; while ((len = getline(line, MAXLEN)) > 0) { if (nlines >= maxlines || (p = malloc(len)) == NULL) return -1; else { line[len-1] = '\0'; // 去除换行符,保证字符串合法 strcpy(p, line); lineptr[nlines++] = p; } } return nlines; }
排序函数中增加指针有效性检查
void qsort(void *v[], int left, int right, int (*comp)(void *, void *)) { int i, last; void swap(void *v[], int, int); if (left >= right) return; swap(v, left, (left+right)/2); last = left; for (i = left+1; i <= right; i++) { // 确保待比较的两个指针都有效 if (v[i] != NULL && v[left] != NULL && (*comp)(v[i], v[left]) < 0) swap(v, ++last, i); } swap(v, left, last); qsort(v, left, last-1, comp); qsort(v, last+1, right, comp); }
内容的提问来源于stack exchange,提问作者coed
相关产品推荐
相关产品推荐

