C语言结构体动态内存分配改造后程序异常问题排查
C语言人员信息管理程序问题根源排查
输入名称时崩溃的原因
- 结构体
name成员改为char*后,未提前分配内存就直接写入:第一阶段的字符数组在栈上有固定存储空间,写入操作安全;改成char*后,该指针默认是野指针(指向随机非法内存地址),直接用scanf("%s", person->name)写入会触发操作系统的内存保护机制,导致程序崩溃。必须先给person->name分配内存,示例代码:
也可使用GNU扩展的#define MAX_NAME_LEN 64 person->name = malloc(MAX_NAME_LEN); if (person->name == NULL) { /* 处理内存分配失败逻辑 */ }scanf("%ms", &person->name)自动分配内存。
设置max_num=3却仅能注册一次的常见根源
- 二级指针未初始化元素为NULL:如果只给
struct PERSON** persons分配了存储3个指针的空间,但未将每个persons[i]初始化为NULL,后续判断空闲位置时,未使用的位置会是随机非NULL值,程序会误认为所有位置都已被占用,无法继续注册。修复代码:struct PERSON** persons = malloc(max_num * sizeof(struct PERSON*)); for (int i = 0; i < max_num; i++) { persons[i] = NULL; } - 注册计数变量或空闲位置判断逻辑错误:比如用
count记录已注册人数时,注册完成后未执行count++;或者遍历二级数组寻找空闲位置时,仅检查第一个位置就退出循环,导致无法找到后续的空闲位置。 - 结构体指针未正确存入二级数组:注册时成功创建了
struct PERSON* p = malloc(sizeof(struct PERSON)),但未将p赋值给二级数组对应的空闲位置,导致下一次循环仍尝试往已占用的第一个位置写入,触发错误逻辑停止。 - 输入缓冲区残留问题:第一次注册输入后,换行符留在标准输入缓冲区,下一次
scanf会直接读取到换行符,误以为输入为空,触发退出逻辑。可在scanf后添加getchar()清理缓冲区,或使用scanf(" %s", ...)(注意开头的空格)跳过空白字符。
内容的提问来源于stack exchange,提问作者Zarr Reese
相关产品推荐
相关产品推荐

