联盟作为C中的结构变量

时间:2015-06-25 23:38:59

标签: c pointers structure unions

我有以下结构:

complex_attribute
generic_attribute

我定义了这两者的联合,如下:

union union_attribute{
    struct complex_attribute *complex;
    struct generic_attribute *generic;
};

然后我定义了另一个跟踪联合的结构和与之关联的代码:

struct tagged_attribute{
    int code;
    union union_attribute *attribute;
};

然后,我定义了另一个名为Disk的结构,它包含一个指向tagger_attribute对象的指针数组:

struct disk {
    struct tagged_attribute *attribute_ptr[100];
}

现在我正在尝试访问标记属性的代码,如下所示:

printf("%i", disk_ptr->attribute_ptr[counter]->code); 

但是我遇到了分段错误。我的方式是访问结构变量"代码"不正确的?

以下是我尝试访问的所有相关代码"代码":

struct disk* construct_disk(char* name, char* serial, char* vendor, char* model, int RPM, char *raid_type, int num_args, ...){
    struct disk *disk_ptr;
    disk_ptr = malloc (sizeof (struct disk));

    va_list ap;
    va_start(ap, num_args);
    int counter;
    int incrementer;
    //subattributes is a global variable
    incrementer = subattributes[counter];

    for(counter = 0; counter < num_attributes; counter++, incrementer = subattributes[counter]){
        printf("Counter = %i\n", counter);
        printf("incrementer = %i\n", incrementer);
        if (1){
            printf("Populating generic attribute");
            printf("%i", disk_ptr->attribute_ptr[counter]->code);
            //disk_ptr->attribute_ptr[counter]->code = GENERIC_ATTRIBUTE_TYPE;
            //disk_ptr->attribute_ptr[counter]->attribute->generic = construct_generic_attribute(va_arg(ap, int));
        }else{
            printf("Populating complex attribute");
            //struct generic_attribute* input_to_complex_attribute[incrementer];
            //int stepper;
            //for(stepper = 0; stepper<incrementer; stepper++){
            //  input_to_complex_attribute[stepper] = construct_generic_attribute(va_arg(ap, int));
            //}
            //disk_ptr->attribute_ptr[counter]->code = COMPLEX_ATTRIBUTE_TYPE;
            //disk_ptr->attribute_ptr[counter]->attribute->complex = construct_complex_attribute(5, incrementer, input_to_complex_attribute);
        }
    }

    va_end(ap);
    return disk_ptr;
}

3 个答案:

答案 0 :(得分:3)

您根本无法访问code(当然,您应该使用它来检查哪个工会会员有效)。

您正在访问counter数组的attribute_ptr元素,该元素是指向tagged_attribute的指针,并尝试取消引用它(使用->) 。可能没有首先分配该指针(或该数组中的任何其他指针),也没有在分配后初始化内存(您还没有显示任何内容......未能正确分配可能是您的段错误的原因。)

当然,这假定disk_ptr已经正确分配和初始化...您尚未展示,也可能没有。

如前所述,如果您想要更具体的问题答案,请显示所有相关代码。此外,在启用警告的情况下进行编译,并学习使用gdb(GNU调试器)和valgrind等工具(用于内存问题)来调试代码。

编辑:既然您已经添加了代码,那么您已经分配了disk_ptr,但是您从未在attribute_ptr中分配任何内容,因此它只有100个指针指向内存中的任意位置

答案 1 :(得分:1)

在C中,如果指针未指向有效内存,则会出现未定义的行为。发生的常见事情之一是分段错误,因为指针具有随机块或初始化为零,当您尝试访问内存时,它指向硬件检测到您正在访问无效的内存页。每次使用->时,您都会取消引用指针并冒着seg错误的风险。您应该使用调试器来查找不正确的值。另一种方法是在取消引用它们之前打印值:

printf("disk_ptr = %p\n", disk_ptr);
printf("disk_ptr->attribute_ptr[counter] = %p\n", disk_ptr->attribute_ptr[counter]);

您应该在显示的打印之前放置此代码。如果disk_ptr是无效值,则第二次打印将失败。第一次打印将始终成功,但您应该看看它是否为NULL。如果您没有看到第二个打印,则表示disk_ptr是无效指针。这是因为在第二次打印中disk_ptr通过->运算符取消引用,如果它指向块,它可以(让我强调可能)导致seg错误(它也可能覆盖一些可能导致seg故障的其他数据)。如果第二次打印有效但您显示的打印没有,则disk_ptr->attribute_ptr[counter]可能是无效指针。让我再次强调,因为它很重要。如果指针未指向正确的内存位置,则表明存在未定义的行为。取消引用该指针可能会导致seg故障,或者可能以某种方式修改内存,以便稍后发生seg故障。

答案 2 :(得分:1)

您正在取消引用disk_ptr->attribute_ptr[1],但该指针数组未初始化(指针指向任何地方)。

首先必须malloc每个指针的struct tagged_attribute个条目。