union中的结构指针:如何初始化和检索结构值

时间:2013-09-09 09:54:55

标签: c

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

这是我编写的一个小示例代码。我想从这段代码中检索“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;

}

1 个答案:

答案 0 :(得分:2)

你确定要一切都在堆上吗?

如果你真的想要,你需要为所有你有指针的结构(或至少你想要访问的结构,例如来自fillDetails)的malloc内存,然后进行清理。你的工会,例如Maker,基本上只是说这个指针可以是两种类型之一,CarVendorBusVendor

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

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;

再次注意,在从fillDetails访问之前,需要对Maker的内存进行malloc,而不是之后。

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