使用getchar与realloc实现字符读取时段错误的修复方案
问题修复方案
你的程序出现段错误的核心原因是对指针和缓冲区操作的逻辑错误,以下是具体问题分析和修复后的代码:
原代码的关键错误
- 指针被错误覆盖:
buffer = getchar();将输入字符的ASCII值直接赋值给指针变量buffer,导致指针指向无效内存地址,这是段错误的直接原因。 - 无缓冲区位置跟踪:没有变量记录下一个字符应该存储在缓冲区的哪个位置,无法正确积累输入内容。
- 未检测EOF:循环没有判断
getchar()返回的EOF(Ctrl+Z触发),导致无限循环无法退出。 - 错误的扩容时机:在未存储字符前就盲目扩容,且扩容后未更新缓冲区大小的有效逻辑。
- 错误的打印方式:
printf("%c", buffer);试图将指针当作字符打印,属于未定义行为。 - 未处理分配失败:内存分配失败后仍继续执行,会引发后续错误。
修复后的代码
#include <stdio.h> #include <stdlib.h> int main() { // 初始缓冲区大小,建议从合理值开始 int size = 4; char* buffer = malloc(size * sizeof(char)); if (buffer == NULL) { fprintf(stderr, "Allocation failed\n"); return 1; } int idx = 0; // 跟踪缓冲区当前存储位置 int c; // 存储getchar()的返回值(必须用int类型处理EOF) printf("Enter characters (Ctrl+Z to end):\n"); while ((c = getchar()) != EOF) { // 检查缓冲区是否已满,需要扩容 if (idx >= size) { // 采用翻倍扩容策略,提升效率 int new_size = size * 2; char* temp = realloc(buffer, new_size * sizeof(char)); if (temp == NULL) { fprintf(stderr, "Reallocation failed\n"); free(buffer); // 释放已分配内存避免泄漏 return 1; } buffer = temp; size = new_size; } // 将字符存入缓冲区 buffer[idx++] = (char)c; } // 打印所有输入的字符 printf("\nYou entered:\n"); for (int i = 0; i < idx; i++) { printf("%c", buffer[i]); } free(buffer); return 0; }
修复说明
- 正确存储输入字符:用
int c接收getchar()的返回值,避免丢失EOF的判断,再将有效字符存入缓冲区的对应位置。 - 缓冲区位置跟踪:新增
idx变量记录当前存储位置,确保每个字符存入正确的位置。 - 合理扩容逻辑:当缓冲区已满时,通过临时指针
temp调用realloc,避免扩容失败时丢失原缓冲区数据,同时采用翻倍策略提升内存分配效率。 - EOF判断退出循环:当用户按下Ctrl+Z时,
getchar()返回EOF,循环终止。 - 正确打印内容:遍历缓冲区的所有存储字符,逐个打印。
- 错误处理优化:内存分配失败时,打印错误信息并释放已分配内存后退出程序,避免内存泄漏和后续错误。
内容的提问来源于stack exchange,提问作者user20082734
相关产品推荐
相关产品推荐

