繁体   English   中英

联合作为C中的结构变量

[英]Union as a Structure Variable in C

我有以下结构:

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

您根本不需要访问code (当然,应该使用该code来检查哪个联合成员有效)。

你访问counter个所述的元件attribute_ptr阵列,这是一个指向tagged_attribute并试图取消引用它(与-> )。 可能没有先分配该指针(或该数组中的任何其他指针),也没有在分配后初始化内存(您未显示任何有关此信息的信息……分配失败可能是导致段错误的原因。)

当然,这假设disk_ptr已正确分配和初始化...您没有显示,也可能没有。

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

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

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

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中通过->运算符取消了引用,并且如果它指向块,则可能(请强调) 可能导致段错误(它也可能会覆盖其他可能稍后导致段错误的数据)。 如果第二个打印有效,但您显示的打印不起作用,则disk_ptr->attribute_ptr[counter]可能是无效的指针。 让我再次强调,因为它很重要。 如果指针未指向正确的内存位置,则您的行为不确定。 取消引用该指针可能会在此处引起段错误,或者可能以某种方式修改内存,从而在以后发生段错误。

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

你要mallocstruct tagged_attribute首先为每个指针的条目。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM