C语言结构体操作触发Segmentation Fault错误求助
账户创建时Segmentation Fault问题排查
问题描述
你编写的C语言账户管理代码在菜单选择选项1创建账户,输入姓名后触发Segmentation Fault错误,错误发生在scanf(" %49s", ptr->name)行。即便将格式符从%50s改为%49s匹配数组大小,问题仍未解决。
原始代码
#include "stdio.h" typedef struct { char name[50]; int money; char IBAN[50]; char passoword[20]; char email[30]; }account; void create_account(account *ptr) { printf("****Welcome to account resgister****\n"); printf("Whats your name?: \n"); scanf(" %49s",ptr->name); printf("Whats your email? : "); scanf(" %29s",ptr->email); printf("Type you password (from 4 to 20): "); scanf(" %19s",ptr->passoword); } int menu() { char option = 0; while(option != '0' && option != '1' && option != '2') { printf("****MENU****\n"); printf("0 - Exit\n"); printf("1 - Create Account\n"); printf("2 - Log in\n"); printf("What you want to do: \n"); scanf(" %c", &option); } return option; } int main (void) { char option; account *ptr; while(option != '0') { option = menu(); switch (option) { case '0': break; case '1': create_account(ptr); break; } } }
问题根源
核心原因是指针ptr未初始化:
在main函数中,你仅声明了account *ptr;,但未给该指针分配有效的内存地址。此时ptr是一个野指针,指向内存中的随机区域。当create_account函数尝试通过ptr->name访问结构体成员时,本质是在访问非法内存空间,直接触发Segmentation Fault。
修复方案
方案1:使用栈上的结构体实例(简单场景推荐)
在main函数中声明栈上的account变量,让指针指向该变量的内存地址:
int main (void) { char option; account acc; // 在栈上分配结构体实例 account *ptr = &acc; // 让指针指向该实例的地址 while(option != '0') { option = menu(); switch (option) { case '0': break; case '1': create_account(ptr); break; } } return 0; // 补充符合C标准的返回值 }
方案2:动态分配内存(多账户/长期存储场景推荐)
通过malloc分配堆内存,使用完成后记得释放避免内存泄漏:
#include "stdio.h" #include "stdlib.h" // 引入stdlib.h用于malloc和free typedef struct { char name[50]; int money; char IBAN[50]; char password[20]; // 修正拼写错误 char email[30]; }account; // 其余函数代码保持不变... int main (void) { char option; account *ptr = NULL; while(option != '0') { option = menu(); switch (option) { case '0': if (ptr != NULL) { free(ptr); // 释放动态分配的内存 ptr = NULL; } break; case '1': if (ptr != NULL) { free(ptr); // 若已有账户,先释放再重新分配 } ptr = (account*)malloc(sizeof(account)); if (ptr == NULL) { // 检查内存分配是否成功 printf("内存分配失败\n"); break; } create_account(ptr); break; } } return 0; }
额外优化建议
- 修正拼写错误:
resgister改为register,passoword改为password menu函数返回值类型改为char,与实际返回的option类型匹配- 所有
scanf的格式符前的空格可以保留,用于跳过输入缓冲区的空白字符,是合理的写法
内容的提问来源于stack exchange,提问作者Dimmezy
相关产品推荐
相关产品推荐

