C语言动态分配字符串实现录入3个姓名后无输出直接退出的问题定位
问题原因与定位思路
- 动态内存结构设计错误
你需要存储3个独立的姓名字符串,本质是需要一组可分别指向独立字符串存储空间的指针,而非单个连续的100字节char缓冲区。当前只申请了一块100字节的连续字符空间,完全不支持存储3个独立字符串的结构需求。 - 输入操作的内存写入位置错误
scanf("%s", &nome[i]);中&nome[i]是取第i个单字符的内存地址,而非预留的字符串写入起始位置。循环过程中,3次输入会依次从nome[0]、nome[1]、nome[2]的位置开始写字符串,直接覆盖前面的内容,还会很快造成内存越界。 - 打印逻辑的循环变量引用错误
第一个录入循环结束后,循环变量i的值已经变为3(循环条件i < 3不再满足才会退出)。后续打印循环里,无论循环变量a遍历到哪个值,代码始终传入nome[i](也就是固定取nome[3]的位置作为字符串起始地址)作为%s的打印参数。这种非法的内存读取会直接触发程序异常退出,根本不会执行预期的打印输出。 - 为何编译没有报错?
这类问题属于C语言典型的未定义行为:- 输入环节的
&nome[i]本身是char*类型,和scanf要求的参数类型完全匹配,编译器不会触发类型报错; - 打印环节传入的
nome[i]是单字符值,按照C语言传参规则会被隐式转换为整数,再被%s解析为内存地址,这种弱校验场景编译器默认不会拦截,直到运行时读到非法内存才会直接退出。
- 输入环节的
正确实现的修正方向
- 用二级指针(指针数组)存储3个姓名的内存地址,先申请可容纳3个
char*的动态内存块;- 为每个姓名单独申请固定长度的字符存储空间;
- 输入时将每个姓名写入对应指针指向的独立空间;
- 打印时遍历指针数组,逐次传入每个字符串的起始地址输出;
- 程序退出前按申请顺序释放所有动态申请的内存,避免内存泄漏。
修正后的参考代码:
#include <stdio.h> #include <stdlib.h> int main(){ int i, componentes = 3; // 动态申请可存储3个姓名地址的指针数组空间 char **nomes = (char**)malloc(sizeof(char*) * componentes); for(i = 0; i < componentes; i++){ // 为每个姓名单独申请100字节的字符存储空间 nomes[i] = (char*)malloc(sizeof(char) * 100); printf("请输入第%d个姓名:", i+1); scanf("%s", nomes[i]); } printf("\n已录入的姓名列表:\n"); for(i = 0; i < componentes; i++){ printf("%s\n", nomes[i]); free(nomes[i]); } free(nomes); return 0; }
内容的提问来源于stack exchange,提问作者Marcos Melo
相关产品推荐
相关产品推荐

