【问题标题】:How is a void pointer dereferenced back to the original struct in C?如何将 void 指针取消引用回 C 中的原始结构?
【发布时间】:2011-08-01 22:31:23
【问题描述】:

我无法为将队列作为链表管理的队列的 C 接口提供结构值。它以空指针的形式保存数据,以允许接口通用地管理任何数据。我将值作为指针引用传递,然后将其保存为 void 指针。后来当它返回时,我不知道如何将 void 指针转换回原始值。

我需要做什么?这是示例结构。

typedef struct MyData {
    int mNumber;
} MyData;

为了简化所有内容,我创建了一个虚拟函数,用几行代码模拟所有内容。

void * give_and_go(void *data) {
    void *tmp = data;
    return tmp;
}

你可以看到它接受一个 void 指针,将它设置为一个局部变量,然后返回它。现在我需要取回原来的值。

MyData inVal;
inVal.mNumber = 100;
void * ptr = give_and_go(&inVal);
MyData outVal; // What converts ptr to the out value?

这就是我卡住的地方。我正在使用 Xcode,它不允许我简单地将 ptr 转换为 MyData 或我尝试过的各种替代方法。

感谢任何帮助。

【问题讨论】:

  • 我发现我可以使用 MyData outVal1 = *(MyData *)ptr;以及 MyData *outVal2 = (MyData *)ptr;回到原始值来访问结构值。这是正确的做法吗?
  • 转换回 (MyData *) 确实是这样做的方法。
  • 请注意,如果您将void* 作为数据成员或函数参数,而没有任何随附的参数/成员,则表示您不在乎其中的内容。但是,如果您稍后将其投放,则必须小心。因此,您要么必须直接传递MyData*(并跳过void* 的想法),要么提供一种方法让您的代码知道它需要转换为MyData*,例如传递enum 说明您的类型,以及void*。让您的代码对其中的内容做出假设会导致棘手的错误,所以请考虑一下..

标签: c xcode4 void-pointers


【解决方案1】:

您应该将 void 指针分配给 MyData 指针:

MyData *outVal = ptr;

如果您使用的是 C++,则必须显式转换它,无论如何我建议这样做,因为它适用于两种语言:

MyData *outVal = (MyData *)ptr;

在任何一种情况下,您都可以使用-> 操作符进行尊重:

outVal->mNumber

您也可以这样分配结构本身:

MyData outVal = *(MyData *)ptr;

但这会复制结构,而其他形式则让您指向原始结构(即,分配给outVal->mNumber 将更改inVal.mNumber,反之亦然)。没有一种或另一种方式的先验偏好。这仅取决于您的意图。

【讨论】:

  • 我没有意识到第二个选项会复制结构。我想在这里的记忆效率很高,所以我会接受第一个建议。谢谢。
  • 只要你知道当你需要一个副本时,你就需要一个副本。
【解决方案2】:

将您的 void* 转换回 MyData*,然后取消引用它。

MyData *outVal = (MyData*)(ptr);

【讨论】:

    【解决方案3】:

    根据我对您提供的代码的了解,您正试图将 void 指针转换回非指针类型。这行不通。

    相反,将您的 void 指针转换回正确类型的 指针

    MyData inVal;
    inVal.mNumber = 100;
    void* ptr = give_and_go(& inVal);
    MyData* outVal = (MyData*)ptr;
    

    【讨论】:

    • 我知道我真的应该首先 malloc 结构,所以我原来的例子很糟糕。我应该安装做 MyData *inVal = (MyData *)malloc(sizeof(MyData));然后我可以传递它并直接转换它,就像我在这里调用 malloc 一样。
    猜你喜欢
    • 2015-01-04
    • 2016-05-12
    • 2011-06-17
    • 2020-04-21
    • 2012-05-23
    • 1970-01-01
    • 2010-09-22
    • 2015-08-04
    • 1970-01-01
    相关资源
    最近更新 更多