如何动态分配结构体内存并存储不同类型数据?解决输入异常问题
问题分析与解决方案
核心问题
- 内存分配不足:原代码里
malloc(sizeof(details))只给单个结构体分配了内存,当输入的n大于1时,会出现越界访问,直接导致程序异常。 - 无法读取带空格的姓名:
scanf("%s")碰到空格、换行就会停止读取,根本没法获取带空格的姓名,而且用%*c清缓冲区的方式不靠谱,容易残留垃圾数据干扰后续输入。 - 用
gets处理整数输入行不通:gets是读取整行字符串的函数,要是输入前缓冲区里剩了换行符,它会直接读个空行,转成int自然就失败了。
修正后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // 新增strchr函数需要的头文件 typedef struct node{ char name[15]; int age; } details; void entry(details*, int); int main() { int n, i; printf("Enter number of details\n"); // 读取数量后彻底清空缓冲区 scanf("%d", &n); while (getchar() != '\n'); // 分配n个结构体的内存,同时检查分配是否成功 details* ptr = malloc(n * sizeof(details)); if (!ptr) { puts("Memory allocation failed"); return 1; } entry(ptr, n); // 输出结果 for(i = 0; i < n; i++) printf("\n%s\n%d\n\n", (ptr+i)->name, (ptr+i)->age); free(ptr); // 释放内存,避免泄漏 return 0; } void entry(details *det, int n) { int i; for(i = 0; i < n; i++){ printf("Enter name:"); // 用fgets读取带空格的姓名 fgets((det+i)->name, sizeof((det+i)->name), stdin); // 去掉fgets读进来的换行符 char *nl = strchr((det+i)->name, '\n'); if (nl) *nl = '\0'; printf("Enter Age:"); scanf("%d", &(det+i)->age); // 读完年龄后清空缓冲区,避免影响下一次姓名输入 while (getchar() != '\n'); } }
关键修改说明
- 内存分配修正:改成
malloc(n * sizeof(details)),确保能装下n条数据,同时加了分配失败的判断,防止空指针出问题。 - 姓名读取替换:用
fgets代替scanf("%s"),它能读取整行内容,包括空格,之后用strchr找到换行符并替换成字符串结束符,避免姓名末尾带换行。 - 缓冲区处理升级:用
while(getchar() != '\n')彻底清空缓冲区,比%*c靠谱多了,不管缓冲区剩多少字符都能清干净。 - 添加内存释放:用完动态内存后必须
free,不然会造成内存泄漏。
注意点
- 结构体里
name数组长度是15,fgets最多读14个有效字符,输入姓名别太长,不然会被截断。 - 要是输入的姓名刚好占满14个字符,
fgets不会读取换行符,这时候后面的缓冲区清理逻辑也不会出错,因为scanf读整数时会自动跳过前面的空白字符。
内容的提问来源于stack exchange,提问作者IndyRose
相关产品推荐
相关产品推荐

