You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

关键修正说明

  1. 修正scanf和printf的参数,直接使用tab[i].brand(char*类型)匹配格式符要求。
  2. 将free(tab[i].brand)移到打印完所有车辆信息之后,避免野指针访问。
  3. 新增isAllAlpha函数,检查品牌字符串的每个字符是否都是字母,确保合法性检查全面。
  4. 添加内存分配失败的判断,增强程序健壮性。

内容的提问来源于stack exchange,提问作者Vandal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 08:57:33