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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:36:00