C语言动态内存重分配异常:首次重分配后无法正常写入字符
问题分析与修复方案
问题根源
- 指针失效:调用
realloc后,内存块可能被移动到新地址,但原指针p仍指向旧的内存位置(已被系统回收或重新分配),后续写入操作会访问无效内存,导致数据丢失或程序行为异常。 - 边界逻辑配合偏差:当前代码中
counter递增时机与扩容判断的配合存在问题,不过核心故障还是指针未随内存重分配更新。
修复步骤
- 更新指针
p:每次realloc后,重新计算p的位置,让它指向新内存块中当前写入的末尾,即p = s + counter;(counter记录已写入字符数,下一个字符应写入该位置)。 - 添加内存分配校验:
malloc和realloc可能分配失败返回NULL,必须添加判断避免空指针操作。 - 优化边界判断:将判断条件调整为
counter >= l - 1,确保在内存耗尽前完成扩容(总容量l需预留一个位置给终止符\0)。
修正后的代码
#include <stdio.h> #include <stdlib.h> #define CHUNK_SIZE 10 int main(void) { int l = CHUNK_SIZE; // s - 用于存储从标准输入读取的字符 char *s = malloc(l * sizeof(char)); if (s == NULL) { perror("malloc failed"); return 1; } char *p = s; // 统计输入字符数的计数器 int counter = 0; int c; // 用int存储getchar返回值,避免EOF判断错误 while ((c = getchar()) != '\n' && c != EOF) { *p++ = c; counter++; // 剩余空间不足时扩容(预留'\0'位置) if (counter >= l - 1) { l += CHUNK_SIZE; char *temp = realloc(s, l * sizeof(char)); if (temp == NULL) { perror("realloc failed"); free(s); return 1; } s = temp; // 更新指针到新内存的当前写入位置 p = s + counter; } } *p = '\0'; printf("%s\n", s); // 释放内存避免泄漏 free(s); return 0; }
额外说明
- 用
int c存储getchar()返回值:getchar()返回int类型(包含EOF),若用char存储会因符号问题导致EOF判断错误。 - 最后必须调用
free(s)释放内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Konstantin Konov
相关产品推荐
相关产品推荐

