【问题标题】:trouble printing pointers to void on structure在结构上打印指向 void 的指针时出现问题
【发布时间】:2016-01-28 19:58:02
【问题描述】:
#include <stdio.h>

typedef struct elem{

    void * d;

}Elem;

main(){

    Elem *p;
    Elem e;

    double pi = 3.14;

    e.d = &pi;
    p->d = &pi;

    printf("%f\n",p->d);
    printf("%f\n",e.d);


}

main.c:25:警告:格式“%f”需要类型“double”,但参数 2 的类型为“void *”

main.c:26:警告:格式“%f”需要类型“double”,但参数 2 的类型为“void *”

我在尝试正确打印此值时遇到问题。 我得到的值与 3.14 无关。

【问题讨论】:

  • *(float*)e.d*(float*)p-&gt;d
  • @im 也是 UB。 %f 需要双倍。它也是UB,因为它指向的对象是double。这违反了严格的别名规则。

标签: c pointers printing void-pointers


【解决方案1】:

在您的代码中,首先,您需要在取消引用之前将内存分配给p。否则,它调用undefined behavior。否则,p 是一个未初始化的指针,并指向一个内存,您的程序可能无法访问该内存,因此本质上是一个无效的内存位置。任何取消引用该指针的尝试都会调用 UB。

之后,

  printf("%f\n",p->d);
  printf("%f\n",e.d);

调用undefined behavior,因为您实际上是在尝试使用%f 格式说明符打印地址。

你要做的,就是去

  1. void 指针转换为 float 指针(因为,您不能取消引用 void *

  2. 然后,解除指针以获取值。

喜欢

  printf("%f\n",*((float *)(p->d)));
  printf("%f\n",*((float *)e.d));    

也就是说,main() 至少应该是 int main(void),这是标准投诉。

【讨论】:

  • 你要做的就是将指针转换为float......因为你不能取消引用void指针。跨度>
  • @hacks 是的,先生,这就是我要写的。我的措辞有其他意思吗?
  • 没有。我只是建议在您的答案中添加它。等待投票。
  • @hacks 谢谢。 :)
【解决方案2】:

你不能这样做:

Elem *p;
[...]
double pi = 3.14;
[...]
p->d = &pi;

...因为p 无处可去。充其量您的程序行为将是未定义的,但最多它会崩溃。做我认为你想要实现的正确代码是:

#include <stdio.h>
#include <stdlib.h>

typedef struct elem {
    void * d;
} Elem;

int main(void) {
    double pi = 3.14;
    // make p point to allocated memory
    Elem *p = malloc(sizeof(*p));
    p->d = &pi;
    // notice the %lf and *(double *)
    // %f is for floats, %lf is four doubles
    // and *(double *) means 'use the value of the pointer (the d field)
    // as the pointer to double type. And then use the value it points to
    printf("%lf\n", *(double *)(p->d));
    return 0;
}

【讨论】:

    猜你喜欢
    • 2016-03-21
    • 2014-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多