0

我有以下简单的代码。我试图了解如何在联合中使用结构以及如何检索与联合相关的结构变量的内容。

这是我编写的一个小示例代码。我想从此代码中检索“Maker”结构变量。我应该如何正确地做到这一点?我的代码在这里导致分段错误。

这是更新的代码:

#include <stdio.h>  
#include <stdlib.h>   

typedef struct{
    char *name;
    int *wheels;
}CarVendor;
typedef struct{
    char *name;
    int *wheels;
    int seats;
}BusVendor;

typedef union{
    CarVendor *carvendor;
    BusVendor *busvendor;
}Maker;
typedef struct{
    Maker *carType;
}Car;
typedef struct{
    Maker *busType;
}Bus;
typedef union{
    Car *car;
    Bus *bus;
}Vehicle;

void fillDetails(Vehicle *vehicle, int type){
    if(type == 0){
        vehicle->car->carType->carvendor->name = "car";
        int wheel = 4;
        vehicle->car->carType->carvendor->wheels = &wheel;
    }
    if(type ==1){
        vehicle->bus->busType->busvendor->name = "bus";
        int wheel = 6;
        vehicle->bus->busType->busvendor->wheels = &wheel;
        vehicle->bus->busType->busvendor->seats = 60;
    }
}

int main(int argc, char *argv[])
{

Vehicle myvehicle;
fillDetails(&myvehicle, 0); //get car details filled & retrieve the details as "Maker" struct
Maker *maker;
maker = (Maker *) malloc(sizeof(Maker));
maker = myvehicle.car->carType;
printf("Name of car =%s", maker->carvendor->name);
return 0;

}

4

1 回答 1

2

你确定你想让所有东西都在堆上吗?

如果你真的想要,你需要为你有指针的所有结构分配内存(或者至少是你想要访问的结构,例如 from fillDetails),然后清理。你的联合,例如Maker,本质上只是说这个指针可以是两种类型之一,要么是 a CarVendor,要么是 a BusVendor

如果您想做这种事情,有时在结构中使用“类型”区分符是有意义的,这样稍后查看它的代码就知道指针具有哪种类型。这是一个例子:

typedef struct a_t_ { /*...*/ } a_t;
typedef struct b_t_ { /*...*/ } b_t;

typedef enum mytype_t_ {a, b} mytype_t;
typedef struct foo_t_ {
    mytype_t type_of_the_below;
    union {
        a_t *a;
        a_t *b;
    };
} foo_t;

再次注意,您需要在Maker从 fillDetails 访问内存之前分配内存,而不是之后。

#include <stdio.h>  
#include <stdlib.h>   

typedef struct{
    char *name;
    int *wheels;
}CarVendor;
typedef struct{
    char *name;
    int *wheels;
    int seats;
}BusVendor;

typedef union{
    CarVendor *carvendor;
    BusVendor *busvendor;
}Maker;
typedef struct{
    Maker *carType;
}Car;
typedef struct{
    Maker *busType;
}Bus;
typedef union{
    Car *car;
    Bus *bus;
}Vehicle;

void fillDetails(Vehicle *vehicle, int type){
    if(type == 0){
        vehicle->car->carType->carvendor->name = "car";
        int wheel = 4;
        vehicle->car->carType->carvendor->wheels = &wheel;
    }
    if(type ==1){
        vehicle->bus->busType->busvendor->name = "bus";
        int wheel = 6;
        vehicle->bus->busType->busvendor->wheels = &wheel;
        vehicle->bus->busType->busvendor->seats = 60;
    }
}

int main(int argc, char *argv[])
{
    Vehicle myvehicle;
    myvehicle.car = (Car*) malloc(sizeof(Car));
    myvehicle.car->carType = (Maker*)malloc(sizeof(Maker));
    myvehicle.car->carType->carvendor = (CarVendor*) malloc(sizeof(CarVendor));
    fillDetails(&myvehicle, 0); //get car details filled & retrieve the details as "Maker" struct
    Maker *maker = NULL;
    maker = myvehicle.car->carType;
    printf("Name of car =%s\n", maker->carvendor->name);
    free(myvehicle.car->carType->carvendor);
    free(myvehicle.car->carType);
    free(myvehicle.car);
    return 0;
}

以下是如何在堆栈上更安全地执行此操作...

#include <stdio.h>  
#include <stdlib.h>   

typedef struct{
    char *name;
    int wheels;
}CarVendor;
typedef struct{
    char *name;
    int wheels;
    int seats;
}BusVendor;

typedef union{
    CarVendor carvendor;
    BusVendor busvendor;
}Maker;

typedef struct{
    Maker carType;
}Car;

typedef struct{
    Maker busType;
}Bus;
typedef union{
    Car car;
    Bus bus;
}Vehicle;

void fillDetails(Vehicle *vehicle, int type){
    if(type == 0){
        vehicle->car.carType.carvendor.name = "car";
        int wheel = 4;
        vehicle->car.carType.carvendor.wheels = wheel;
    }
    if(type ==1){
        vehicle->bus.busType.busvendor.name = "bus";
        int wheel = 6;
        vehicle->bus.busType.busvendor.wheels = wheel;
        vehicle->bus.busType.busvendor.seats = 60;
    }
}

int main(int argc, char *argv[])
{
    Vehicle myvehicle;
    fillDetails(&myvehicle, 0); //get car details filled & retrieve the details as "Maker" struct
    Maker *maker;
    maker = &myvehicle.car.carType;
    printf("Name of car =%s\n", maker->carvendor.name);
    return 0;
}
于 2013-09-09T12:35:04.800 回答