Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-动态地将void指针转换为结构_C_Struct_Void Pointers - Fatal编程技术网

C-动态地将void指针转换为结构

C-动态地将void指针转换为结构,c,struct,void-pointers,C,Struct,Void Pointers,我想根据变量的值将指针强制转换为两种结构之一。我正在尝试,但它不起作用- struct typeA { int a; int x; } struct typeB { int b; int a; int x; int z; } int band=1; void *ptr; if(band == 1) ptr = (struct typeA *)malloc(sizeof(struct typeA)); els

我想根据变量的值将指针强制转换为两种结构之一。我正在尝试,但它不起作用-

struct typeA
{
     int a;
     int x;
}
struct typeB
{
     int b;
     int a;
     int x;
     int z;
}


int band=1;
void *ptr;

if(band == 1)
            ptr = (struct typeA *)malloc(sizeof(struct typeA));
else if(band == 2)
            ptr = (struct typeB *)malloc(sizeof(struct typeB));

printf("A:%d",ptr->a);//error: structure type required instead of void
最好的方法是什么


编辑:添加结构定义和错误(在代码注释中)以使其更有意义。

如果您不需要知道所使用的结构类型,请使用

if(band == 1)
        ptr = malloc(sizeof(struct typeA));
else if(band == 2)
        ptr = malloc(sizeof(struct typeB));
的返回类型已经是
void*

然而,这是一个---你真的不需要在你创建它之后知道它的大小或类型吗?我会重新考虑一下你的设计


编辑根据您发布的其他代码,我强烈推荐一种新方法。例如,
typeA
typeB
中的字段顺序不同,因此无论
ptr
的类型如何,
ptr->a
都无法引用这两个字段。如果您使用了纯C,请考虑一个<代码>结构> <代码>,它有<代码> < <代码> >代码> x>代码>,以及一个可选的指针,指向一个单独的结构,它具有“代码> b<代码>和<代码> z <代码>。或者,只需对所有内容使用
typeB
,然后删除
typeA

您不应该强制转换malloc的结果,因为这样做可能会掩盖其他问题。因为类型不匹配,所以在这里也会引起警告

摆脱强制类型转换,您将不会收到任何警告

编辑:

该错误是因为您试图取消对
无效*
的引用,这是非法的


使用两个变量(每种类型一个)并将另一个设置为NULL,而不是使用一个变量。或者,如果您知道
void*
所指向的数据类型,您可以将其转换为正确的类型,然后取消引用。

这里的转换不会给您带来任何好处,因为每次转换的结果都会立即转换为
ptr
的类型。无论哪种方式,指向
malloc
-ed对象的指针最终存储在
ptr
中,并且
ptr
有一个与
malloc
返回的内容完全匹配的静态类型。唯一不同的行为是
malloc
-ed区域的大小

您的逻辑可以简化为一行:

void *ptr = malloc(band == 1 ? sizeof (struct typeA) : sizeof (struct typeB));
对于周围的代码,这是否是一种很好的方法,或者更严格的“面向对象的”方法是否更好,或者在两段独立的代码之间进行简单的切换是否在独立的结构上工作,都需要更多的上下文

如果没有额外的强制转换,实际对象不能作为
typeA
typeB
访问,因此可以想象会出现很多丑陋的代码,例如

if (band == 1)
   do_this_A_version((struct typeA *) ptr)->foo, x);
else
   do_this_B_version((struct typeB *) ptr)->bar, y);
有一些很好的方法可以避免这类问题,超出了这个问题的范围。

[p>[EDIT]代码段在OP编辑后更新

这是对实际问题的二次猜测,但也许下面是什么 你在找我

struct typeA
{
    int a;
    int x;
};
struct typeB
{
    int b;
    int a;
    int x;
    int z;
};

union { struct typeA *A; struct typeB *B; } ptr;
if(band == 1)
    ptr.A = malloc(sizeof(struct typeA));
else if(band == 2)
    ptr.B = malloc(sizeof(struct typeB));

/* ... later on ... */

if(band == 1)
    printf("A::a = %d", ptr.A->a); /* use ptr.A as a struct typeA pointer */
else if(band == 2)
    printf("B::a = %d", ptr.B->a); /* use ptr.B as a struct typeB pointer */

正如其他人所建议的,您可能需要更改您的设计,因为它有一些缺陷

但是,要解决出现的编译错误,可以执行以下操作:

 printf("A:%d",(band == 1) ? ((struct typeA *)ptr)->a : ((struct typeB *)ptr)->a);
出现错误是因为您试图从
void*
访问成员
a
,而您这样做(
ptr->a


你需要明确地说,
ptr
指向一个
struct typeA
struct typeB

在C中不需要强制转换(同样
ptr
void*
),请解释“不工作”。我否决了,因为你说你的代码不工作,但你没有说明原因,编译器给你的错误或警告是什么。提供此信息修改您的问题,我将删除我的否决票。停止播放
malloc()
,但一定要为
ptr
指定一个真实类型。如果事实上有很好的理由让
ptr
be
void*
那么为什么不分配两种尺寸中较大的一种呢?而且,“它不起作用”是对你问题的可怕描述。包括错误消息!哎呀,那不行。编译器需要知道
ptr
指向什么类型。我想你可以在每次使用它时施放
ptr
,但是哇,那会很难看。严格地说,您必须将指针指向其原始类型。(一个被广泛忽视的规则。)这是高级的C,现在,声明两个不同类型的指针。
if(band==1){ptr=malloc(sizeof(struct typeA));/*…set A...*/printf(“A:%d\n,((struct typeA*)ptr)->A);}如果(band==2){ptr=malloc sizeof(struct typeB));printf
类型不匹配,但
void*
是最通用的指针类型,因此将指向任何其他类型的指针分配给
void*
应该没有问题,或者我错了吗?不是选民。