C语言多次调用malloc触发SIGABRT报错,读取输入行程序问题排查
问题原因排查
- 堆内存溢出(触发SIGABRT的直接原因):代码中仅调用
malloc(sizeof(char))分配1字节内存,仅能存储1个字符,后续l++后写入的位置均属于已分配内存外的非法空间,会直接破坏堆上malloc维护的块元数据,下一次调用malloc时检测到元数据损坏就会触发SIGABRT。 - 指针
l未重置导致未定义行为:外层循环每处理新一行时,没有重置l的值,上一行处理结束后l已经指向旧行的末尾位置,新一行内层循环初始阶段*line为NULL,执行(l - *line)的指针减法属于非法操作,运行结果完全不可预期。 - 字符串终止符写入越界:内层循环退出条件包含
(l - *line) != MAXLINE,退出时l刚好指向偏移MAXLINE的位置,此时写入\0会超出最大长度限制,且代码未为终止符预留分配空间。 - 缺少边界防护:外层循环没有判断当前是否超出
line数组的最大容量MAXLINES,会导致指针数组越界写入。
修复代码
#include <stdio.h> #include <stdlib.h> #define MAXLINES 100 #define MAXLINE 100 // 提前声明函数避免隐式声明警告 void getlines(char **line); int main() { char *line[MAXLINES]; getlines(line); // 后续使用完line数组后,记得遍历free每行内存避免泄漏 return 0; } void getlines(char **line){ int c = 0; int line_cnt = 0; // 控制不超过指针数组最大容量,预留最后一位存NULL while(c != EOF && line_cnt < MAXLINES - 1) { // 一次性分配足够存储一行的空间,多留1字节存字符串终止符 char *cur_line = malloc(MAXLINE + 1); if (cur_line == NULL) { perror("内存分配失败"); exit(EXIT_FAILURE); } int pos = 0; while(pos < MAXLINE && (c = getchar()) != EOF && c != '\n') { cur_line[pos++] = c; } cur_line[pos] = '\0'; line[line_cnt++] = cur_line; // 跳过换行符避免下一行读取到空内容 if (c == '\n') c = getchar(); } line[line_cnt] = NULL; }
内容的提问来源于stack exchange,提问作者Haznut
相关产品推荐
相关产品推荐

