C语言写入结构体指针时触发Segmentation fault错误求助
段错误(Segmentation Fault)问题分析与修复
核心错误点
- scanf参数类型不匹配:
scanf("%s", *tab[i].brand);中,tab[i].brand是char*类型(malloc分配的字符数组首地址),而*tab[i].brand取的是数组第一个字符(char类型)。scanf("%s")需要接收char*类型的地址,直接传tab[i].brand即可,传*tab[i].brand会导致非法内存访问,触发段错误。 - 提前释放内存导致野指针:输入完单辆车的信息后立刻执行
free(tab[i].brand);,后续打印时再访问tab[i].brand属于访问已释放的野指针,必然引发段错误。 - printf格式符与参数不匹配:
printf("Brand: %s\n", *tab[i].brand);中,%s需要char*类型参数,但*tab[i].brand是char类型,类型不匹配会导致未定义行为。 - 品牌合法性检查不严谨:仅检查字符串第一个字符是否为字母,无法过滤包含数字/符号的品牌名称(如"BMW2024"会被误判为合法)。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> struct Car { double price; char *brand; }; // 检查字符串是否全为字母 int isAllAlpha(const char *str) { for (int i = 0; str[i] != '\0'; i++) { if (!isalpha(str[i])) { return 0; } } return 1; } void createAndPrint(int n, struct Car *tab) { for (int i = 0; i < n; i++) { // 分配足够内存存储品牌(含结束符) tab[i].brand = malloc(sizeof(char) * 100); if (tab[i].brand == NULL) { printf("内存分配失败!\n"); exit(1); } printf("\nENTER DETAILS FOR CAR NO %d\n", i + 1); do { printf("Enter price: "); scanf("%lf", &tab[i].price); if (tab[i].price < 0) { printf("Price cannot be < 0!\n"); } } while (tab[i].price < 0); do { printf("Enter brand: "); // 直接传char*类型的tab[i].brand给scanf scanf("%s", tab[i].brand); if (!isAllAlpha(tab[i].brand)) { printf("Brand must consist of letters only!\n"); } } while (!isAllAlpha(tab[i].brand)); } // 打印所有车辆信息 for (int i = 0; i < n; i++) { printf("\nCAR INFORMATION NO %d\n", i + 1); printf("Price: %.2lf\n", tab[i].price); // 直接传char*类型的tab[i].brand给printf printf("Brand: %s\n", tab[i].brand); // 打印完成后再释放内存 free(tab[i].brand); } } int main() { int n; printf("Enter the number of cars: "); scanf("%d", &n); struct Car *tab = malloc(n * sizeof(struct Car)); if (tab == NULL) { printf("内存分配失败!\n"); return 1; } createAndPrint(n, tab); free(tab); return 0; }
关键修正说明
- 修正
scanf和printf的参数,直接使用tab[i].brand(char*类型)匹配格式符要求。 - 将
free(tab[i].brand)移到打印完所有车辆信息之后,避免野指针访问。 - 新增
isAllAlpha函数,检查品牌字符串的每个字符是否都是字母,确保合法性检查全面。 - 添加内存分配失败的判断,增强程序健壮性。
内容的提问来源于stack exchange,提问作者Vandal
相关产品推荐
相关产品推荐

