请求验证entry2_Player函数正确性及返回变量有效性
entry2_Player函数验证与修复建议
给定函数要求
输入为包含姓名、空格和整数得分的字符串(如"Sam 67"),函数需执行以下操作:
- 打印
malloc() for "Sam 67" ...;- 尝试为Player结构体分配内存:若malloc失败,打印
Failed! Returning NULL并返回NULL;- 通过sscanf解析entry到Player的姓名和得分,若解析成功(*n=2),打印
at address: 0x000....并返回分配的内存地址;- 若输入无效(如"Sam45"),释放已分配内存,打印
Invalid entry string! Returning NULL并返回NULL。
现有代码
#include <stdio.h> #include <stdlib.h> #include <ctype.h> // Room for a short name string in Player: #define NAME_SIZE 10 // Incremental number of memory, in units of pointers, by which to increase // size of Player pointer array: #define MALLOC_INCR 5 typedef struct { char name[NAME_SIZE] ; int score ; } Player ; Player * entry2_Player(char *entry, int *n) { char name[10]; int score; printf("\nmalloc() for %s ...", entry); Player *pID = (Player *)malloc(sizeof(entry)); if (pID == NULL){ printf("Failed! Returning NULL"); return NULL; } *n = sscanf(entry, "%s %d", name, &score); if (*n !=2){ printf("Invalid entry string!"); free(pID); return NULL; } else{ printf("at address: 0x%p", &n); return pID; } }
核心问题分析(含返回变量正确性验证)
你的entry2_Player函数存在多处不符合要求的问题,且返回变量的可用性存在严重缺陷:
- 内存分配错误:
malloc(sizeof(entry))分配的是指针entry的大小(通常4/8字节),而非Player结构体的大小,导致分配的内存空间不足以存储姓名和得分,后续写入会触发内存越界,返回的指针虽然非空,但属于非法内存区域。 - 结构体数据未填充:解析得到的
name和score仅存在局部变量中,未写入到分配的pID指向的结构体中,返回的指针指向的是未初始化的垃圾数据,完全无法满足后续show_Player()等函数的使用需求。 - 地址打印错误:
printf("at address: 0x%p", &n)打印的是参数n的指针地址,而非分配的Player结构体地址,不符合要求中打印内存地址的要求。 - 提示信息不完整:输入无效时仅打印
Invalid entry string!,缺少要求的Returning NULL;malloc失败的打印无换行,格式不符合预期。 - 缓冲区溢出风险:
sscanf解析姓名时未限制长度,若输入姓名超过9字符(NAME_SIZE-1),会导致局部变量name溢出。
综上,当前函数返回的指针要么是非法内存(malloc大小错误),要么是未初始化的无效结构体,完全不符合要求,无法用于后续main函数的任务。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // 需添加string.h用于字符串操作 #define NAME_SIZE 10 #define MALLOC_INCR 5 typedef struct { char name[NAME_SIZE] ; int score ; } Player ; Player * entry2_Player(char *entry, int *n) { Player *pID = (Player *)malloc(sizeof(Player)); if (pID == NULL){ printf("\nmalloc() for %s ...Failed! Returning NULL\n", entry); return NULL; } printf("\nmalloc() for %s ...", entry); // 限制姓名长度为NAME_SIZE-1,避免缓冲区溢出 *n = sscanf(entry, "%9s %d", pID->name, &pID->score); if (*n != 2){ printf("Invalid entry string! Returning NULL\n"); free(pID); return NULL; } else{ printf("at address: 0x%p\n", (void*)pID); return pID; } }
修复说明
- 修正内存分配:使用
sizeof(Player)分配足够存储结构体的内存,确保返回的指针指向合法且足够的内存区域。 - 填充结构体数据:直接将sscanf的结果写入
pID指向的结构体成员,确保返回的指针包含有效的姓名和得分数据。 - 修正地址打印:打印
pID的地址(转换为void*保证跨平台兼容性),符合要求的输出格式。 - 完善提示信息:补全所有要求的打印内容,添加换行保证输出整洁。
- 避免缓冲区溢出:使用
%9s限制姓名输入长度,匹配NAME_SIZE的定义。
后续任务适配
修复后的函数返回的指针是合法且填充了有效数据的Player结构体地址,可以安全用于:
- 使用"Robin 78"调用函数创建Player变量,传递给
show_Player()展示 - 将返回的指针存入Player指针数组,包括添加第五个Player的操作,最终用
show_Players()展示数组
内容的提问来源于stack exchange,提问作者Mr.Mok
相关产品推荐
相关产品推荐

