【问题标题】:Issue in passing a structure to a function accepting void * parameter将结构传递给接受 void * 参数的函数时出现问题
【发布时间】:2015-07-08 17:53:42
【问题描述】:

我想调用一个foo(void * data) 类型的函数,它的输入参数是一个结构变量。

我听说当输入格式是 void 类型时,它接受所有类型的输入变量类型。不过,我收到一条错误消息。

struct info{
    int element;
};

struct info inserter_info;
inserter_info.element = 0;

inserter(inserter_info);

inserter() 的原型是void * inserter(void * data)

我尝试投射,但也收到错误消息。

【问题讨论】:

  • 什么您收到错误消息?在发布有关错误的问题时,请始终在问题中包含实际错误(完整且未经编辑)。请编辑您的问题以包含该信息。
  • 你可以在这里找到一些相关信息stackoverflow.com/q/23805910/2436175

标签: c pointers struct parameter-passing void


【解决方案1】:

听说当输入格式是void类型时,它接受每一种输入变量类型

绝对错误! void 表示什么都没有。它接受什么都不接受。

不过,void *被认为是一个通用指针。引用C11 标准文档,第 6.3.2.3 章,指针,第 1 段,

指向 void 的指针可以转换为或从指向任何对象类型的指针转​​换。指向任何对象类型的指针可以转换为指向 void 的指针并再次返回;结果应与原始指针比较。

使用这个属性,很多时候,函数参数写成void *,这样函数就可以接受不同类型的指针,然后在函数体内,根据其他一些参数,接收到的指针被转换(强制转换)在使用它之前返回实际的指针类型。

如果检查正确,该函数的参数不是void,而是void *

你需要像这样调用你的函数

inserter(&inserter_info);

P.S - 你的编译器应该警告你不匹配。

【讨论】:

  • 然后我怎么能得到元素的值?我试过 int a = (int) data.element;在 inserter 方法中,但会引发编译错误
  • @user1920212 不,不是那样的。采取struct info * if = data; int a = if->element;。希望这可以解决问题。坦率地说,如果你对指针不太熟悉,我建议你先了解一下基础知识。
【解决方案2】:

void *data 期待一个指针

这里:

struct info inserter_info;
inserter_info.element = 0;
inserter(inserter_info);

你没有传递指针,改为:

inserter(&inserter_info);

【讨论】:

    【解决方案3】:

    它需要一个指针,但你没有传递一个指针,如果inserter() 函数要在不同的线程中运行,你需要在堆上分配结构,否则它将在线程启动时被释放。

    struct info {
        int element;
    };
    
    struct info *inserter_info;
    inserter_info = malloc(sizeof(*inserter_info));
    if (inserter_info == NULL)
        abortThisOperation();
    inserter_info->element = 0;
    
    inserter(inserter_info);
    

    你应该确保当线程完成工作时你会释放分配的指针。

    如果函数不打算从不同的线程运行,那么像这样传递结构的地址

    struct info inserter_info;
    inserter_info.element = 0;
    
    inserter(&inserter_info);
    

    足够了。

    【讨论】:

      【解决方案4】:

      听说当输入格式是void类型时,它接受所有类型的输入变量类型

      指向 void 的 指针 接受任何其他指向 对象类型 的指针。 void* 和指向 函数类型 的指针之间的转换是未定义的行为,标准未涵盖它。

      标准仍然将此列为“通用语言扩展”,这意味着此类转换在您的给定系统上可能是可以的,但前提是您的编译器已实现非标准扩展。

      实际上,指针几乎总是直接对应于原始 CPU 地址,在这种情况下,变量地址和函数地址之间通常没有区别。因此,在 C 标准之外的现实世界中,您可能会摆脱这种强制转换。

      否则,您可以“破解 C 标准”,首先将函数指针转换为整数类型(例如 uintptr_t),然后从那里将其转换为 void*。在这种情况下,代码只会在指针不能表示为整数(这不太可能)的情况下调用未定义的行为。

      【讨论】:

        猜你喜欢
        • 2013-10-19
        • 1970-01-01
        • 1970-01-01
        • 2017-10-21
        • 1970-01-01
        • 2021-11-19
        • 1970-01-01
        • 2015-09-10
        • 1970-01-01
        相关资源
        最近更新 更多