用C语言开发QuizMaker遇步骤遗漏问题,求代码排查帮助
QuizMaker 代码问题修正与优化
原代码存在的问题
- 变长数组兼容性问题:
char *strarr[a];是C99引入的变长数组(VLA),部分编译器(如MSVC)不支持,建议改用动态分配指针数组。 - 内存分配未预留终止符空间:
malloc((length) * sizeof(char))没有为字符串结束符\0预留空间,会导致strcpy越界写入引发未定义行为,应改为length + 1。 - input函数的终止符赋值问题:原input函数中
str[i] = '\0';放在while循环内,当输入字符数达到n时,i等于n,此时str[i]会越界访问数组(数组下标最大为n-1),应将终止符赋值移到循环结束后,并确保不超出数组范围。 - 内存泄漏:未释放
malloc分配的内存,程序退出前需要逐个释放每个字符串的内存。 - 输入错误未处理:
scanf("%d", &a);如果用户输入非数字,会导致a的值未定义,需要检查scanf的返回值处理输入错误。 - 缓冲区清空的EOF处理:原
while (getchar() != '\n');在遇到EOF时会陷入死循环,需要判断getchar的返回值是否为EOF。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFFER_SIZE 4096 int input(char *str, int n); int main() { int question_count, i, length = 0; printf("How many questions do you want?\n"); // 处理题目数量输入错误 if (scanf("%d", &question_count) != 1 || question_count <= 0) { fprintf(stderr, "Invalid input! Please enter a positive integer.\n"); return 1; } // 动态分配指针数组,替代变长数组提升兼容性 char **strarr = malloc(question_count * sizeof(char*)); if (strarr == NULL) { fprintf(stderr, "Memory allocation failed!\n"); return 1; } char buffer[BUFFER_SIZE]; // 临时存储输入的字符串 // 清空scanf后的输入缓冲区,处理EOF情况 int ch; while ((ch = getchar()) != '\n' && ch != EOF); for(i = 0; i < question_count; i++) { printf("Question number #%d:\n", i + 1); length = input(buffer, BUFFER_SIZE); // 为字符串分配内存,包含终止符空间 strarr[i] = malloc((length + 1) * sizeof(char)); if (strarr[i] == NULL) { fprintf(stderr, "Memory allocation failed for question %d!\n", i+1); // 释放已分配的内存避免泄漏 for(int j = 0; j < i; j++) { free(strarr[j]); } free(strarr); return 1; } strcpy(strarr[i], buffer); } // 打印结果 printf("_____________\n"); for(i = 0; i < question_count; i++) { printf("%s\n", strarr[i]); } // 释放所有动态分配的内存 for(i = 0; i < question_count; i++) { free(strarr[i]); } free(strarr); return 0; } int input(char *str, int n) { int ch, i = 0; while ((ch = getchar()) != '\n' && ch != EOF) { if (i < n - 1) { // 预留一个位置给终止符 str[i++] = ch; } // 超出长度的字符直接丢弃 } // 循环结束后添加终止符,确保字符串合法 str[i] = '\0'; return i; }
优化说明
- 改用
char **strarr = malloc(...)动态分配指针数组,兼容所有标准C编译器。 - 内存分配时增加
+1的空间,确保能存储字符串终止符。 - input函数调整终止符赋值逻辑,避免越界同时处理EOF情况。
- 增加内存分配失败的错误处理,避免程序崩溃。
- 处理题目数量的输入错误,确保输入为正整数。
- 程序退出前释放所有动态分配的内存,消除内存泄漏。
内容的提问来源于stack exchange,提问作者Bilguun Batsaikhan
相关产品推荐
相关产品推荐

