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

C语言读取≥27字符行时realloc崩溃问题求助

解决realloc(): invalid next size报错问题

问题背景

我编写了一个基于fork的归并排序变体C程序,实现了getInputLine函数从指定输入流读取整行内容,末尾添加'\0'并返回布尔值指示是否存在换行符。但当输入行长度超过26字符时,触发错误:realloc(): invalid next size Aborted (core dumped)。

函数代码如下:

static bool getInputLine(FILE *f, char **input, int *size_in) {                                                                                              
    int size = 0;                                                                                                                                             
    char todo;                                                                                                                                                
                                                                                                                                                              
    do {                                                                                                                                                      
        if((*input = realloc(*input, (size + 1) * sizeof(char))) == NULL) exitWithStatus(EXIT_FAILURE, "reallocing FAILED");                                  
        todo = fgetc(f);                                                                                                                                      
        if(todo == EOF) break;                                                                                                                                
        (*input)[size] = todo;                                                                                                                                
        if(todo == '\n' && size == 0){                                                                                                                        
            fprintf(stdout, "\n");                                                                                                                                                                                                                                                            
            break;                                                                                                                                            
        }                                                                                                                                                     
        size++;                                                                                                                                               
    } while(todo != '\n');                                                                                                                                    
                                                                                                                                                              
    if((*input = realloc(*input, (size+1) * sizeof(char))) == NULL) exitWithStatus(EXIT_FAILURE, "reallocing FAILED");                                        
                                                                                                                                                              
    (*input)[size] = '\0';                                                                                                                                    
    *size_in = size;                                                                                                                                          
                                                                                                                                                              
    return size == 0 || todo != '\n';                                                                                                                         
}  

调用该函数前已用malloc(sizeof(char))为输入字符串分配初始内存,进程退出时会释放该内存,操作系统为Linux Fedora。

问题分析与修复建议

1. 代码本身的潜在问题

  • fgetc返回值类型不匹配:fgetc返回int类型(包含EOF值,通常为-1),但代码中用char todo接收。若系统中char为无符号类型,todo永远无法等于EOF,会引发死循环进而破坏堆结构,应改为int todo;。
  • 空行处理冗余:读取到首字符为'\n'时,额外执行fprintf(stdout, "\n")属于多余操作,可直接移除。

2. 核心问题:fork导致的堆结构损坏

你推测的方向正确——fork子进程继承全局变量/堆指针会引发堆元数据冲突。

fork后,父子进程的地址空间采用写时复制机制,但堆的管理元数据(如内存块空闲链表)会被完整复制。若父子进程同时对同一块堆内存执行realloc/free操作:

  • 父进程修改堆元数据后,子进程的元数据会过时失效
  • 子进程再执行内存分配操作时,会访问无效的堆元数据,触发realloc(): invalid next size这类错误

3. 解决方案

  • 避免fork后共享堆内存:fork前完成所有输入读取,或让父子进程各自维护独立的输入缓冲区(比如fork后,子进程重新分配自己的内存,不使用继承的指针)。
  • 隔离内存操作:确保每个进程的内存分配/释放操作仅在自身地址空间内进行,禁止父子进程操作同一块堆内存。

后续处理

虽经多方协助仍未定位到具体损坏点,最终重新设计了整体解决方案,推测问题根源确实是fork子进程继承全局变量导致的堆结构损坏。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 14:45:27