【问题标题】:Accessing structs and void pointers访问结构和空指针
【发布时间】:2015-04-06 14:27:58
【问题描述】:

我读到 void 指针可以从任何指针隐式转换为,但似乎它们不适用于结构,我举了一个例子:

typedef struct FOO{
    int *arr;
    size_t size;
} FOO;

int main()
{
    void * a;
    FOO * b = (FOO*)malloc(sizeof(FOO));

    a = b;

    b->arr;//works, accessed arr
    a->arr;//error: expression must have pointer-to-struct-or-union type
}

我可以看到ab 有相同的地址,但我不能使用a,因为它与b 的类型相同,这是为什么呢?

另一个相关的问题是,绝对可以将任何指针隐式转换为void * 吗?比如FOO****void*

【问题讨论】:

  • 标准警告:请do not castmalloc()C 中的家人的返回值。
  • @SouravGhosh 嗯,我使用 VS,所以这是我所知道的标准......
  • 对于您的相关问题,除了指向函数的指针之外,任何指针都不能保证它们的大小。
  • 对于词汇表,C 中的 casts 是那些你在前面写(void*) 之类的转换。这些是显式 转换,您的代码通常不应包含其中任何一个。您在 a = b 中所做的是从另一个指针类型 void* 的隐式转换。
  • 为什么代码不应该包含显式转换? @JensGustedt

标签: c pointers syntax struct


【解决方案1】:

a->arr; 等价于(*a).arr;a 属于 void * 类型,不能取消引用。在取消引用之前,您需要将 a 转换为 FOO *

((FOO *)a)->arr;

【讨论】:

  • 但是a=b 不是将a 转换为FOO* 类型吗?
  • 不,这不是强制转换,而是转换。
【解决方案2】:

您可以将任何指针类型分配给void *,但如果您想取消引用它,您需要将其转换回。否则,无法知道结构。 void 没有结构/成员,也没有机制来假设 void * 指向的内存的可能有效类型。

【讨论】:

    【解决方案3】:

    考虑一下你的例子会更清楚

    #include <stdlib.h>
    #include <time.h>
    
    typedef struct FOO1{
        int *arr;
        size_t size;
    } FOO1;
    
    typedef struct FOO2{
        int *arr;
        size_t size;
    } FOO2;
    
    int main()
    {
        void * a;
    
        srand( ( unsigned int )time( NULL ) );
    
        int x = rand();
    
        if ( x % 2 == 0 )
        {  
            a = malloc( sizeof( FOO1 ) );
        }
        else
        {
            a = malloc( sizeof( FOO2 ) );
        }
    
        a->arr;
    }
    

    你能说一下对象指针 a 指的是什么吗?:)

    类型void 是不完整的类型。您可能会注意到定义类型为 void 的对象。但是这个表情

    a->arr;
    

    看起来像“访问 void 类型对象的数据成员 arr”。:)

    为了编译上面的程序,你必须写一些类似的东西

    if ( x % 2 == 0 ) ( ( FOO1 * )a )->arr = NULL;
    else ( ( FOO2 * )a )->arr = NULL;
    

    也就是说,您需要将指针转换为您要访问的对象的类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-05
      • 2021-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-03
      相关资源
      最近更新 更多