【问题标题】:C trying to cast a void pointer to another typeC 试图将 void 指针转换为另一种类型
【发布时间】:2012-03-14 12:43:06
【问题描述】:

好的,代码如下:

//in another file

void **ptr; ptr = kmalloc(sizeof(void *) * 2);

  *(ptr+0) = tf; //type trapframe *
  *(ptr+1) = as; //type addrspace *

func(*ptr); 

这是这个函数:

void func(void *ptr) {

struct trapframe *parentTF = ptr[0];
struct addrspace *newAS = ptr[1]; 
//now I wanna do stuff with parentTF and newAS

}

我得到的错误是:

warning: dereferencing `void *' pointer

感谢您的帮助。

【问题讨论】:

    标签: c pointers void void-pointers


    【解决方案1】:

    您将ptr 声明为void **,但将其用作void *。它们是不同的。

    【讨论】:

      【解决方案2】:

      func 中,ptr 被声明为void*ptr[0]*ptr 相同,ptr[1]*(ptr + 1) 相同。正如您的编译器告诉您的那样,您正在尝试取消引用 void 指针。

      如果您想将void 指针数组传递给func,则需要进行以下更改:

      • func的签名改为:

        void func(void **ptr)

      • func(*ptr); 更改为简单的func(ptr); 以将动态分配的数组ptr 传递给函数。

      我也不明白你为什么要将顶部 sn-p 中ptr 的声明和初始化分成两个语句。只要有:

      void **ptr = kmalloc(sizeof(void *) * 2);
      

      甚至:

      void **ptr = kmalloc(sizeof(*ptr) * 2);
      

      【讨论】:

        【解决方案3】:

        如果我正确理解了您要执行的操作,那么您似乎需要更改此设置:

        void func(void *ptr) {
        

        到这里:

        void func(void **ptr) {
        

        还有这个:

        func(*ptr);
        

        到这里:

        func(ptr);
        

        请注意,*(ptr+0)ptr[0] 是同义词,*(ptr+1)ptr[1] 也是。

        【讨论】:

        • 是的,我试图让自己相信指针和数组的相似之处。非常感谢,我认为这些更改有效。老实说,即使我应该已经知道 C 3 年了,但我确实很难使用指针。有点悲伤。
        • @YoungMoney:不客气。我认为普遍的共识是指针很难。而 C,当你弄错时,它倾向于陷入“未定义的行为”而不是“打印堆栈跟踪并退出”,似乎旨在使其更难。 :-P
        • 这取决于您来自哪里。由于我多年来一直使用汇编语言进行编程,因此指针(简单的机器地址)和指针变量(简单的寄存器或保存地址的位置)的想法似乎很直观。再加上类型化指针的概念,特定类型对象的地址,你就完成了,除了摸索语法,应该从右到左阅读(例如,指向 void 的指针)。
        【解决方案4】:

        首先将 void 指针数组转换为所需指针类型的数组。即,您需要进行此类更改:

        ((trapframe **)ptr)[0] = tf; //type trapframe *

        还有这样的演员:

        struct trapframe *parentTF = ((trapfname**)ptr)[0];

        【讨论】:

        • 因为这是C,所以struct关键字是必须的。而且由于 ptr 指向一个同时包含 struct trapframe *struct addrspace * 的数组,因此这些转换是不准确的。正确的是ptr[0] = (void *)tf;ptr[0] = tf; /* cast to void* isn't needed in C */struct trapframe *parentTF = (struct trapframe *)ptr[0];(当然,更正确的是声明ptr 指向一个包含struct trapframe *struct addrspace * 的结构。)
        【解决方案5】:

        你期待什么?函数的参数ptr 是指向“某物”的指针(即void)。您使用ptr[0]ptr[1] 取消引用该指针,试图提取“某些东西”。但编译器不知道“某物”的类型或大小。

        你可能想要的是这个:

        func(ptr);
        

        还有这个:

        void func(void** ptr)
        {
        ...
        }
        

        【讨论】:

          【解决方案6】:

          由于两个文件之间的不一致,您的代码大错特错。在一个中,您访问 ptr[0] 和 ptr[1],而在另一个中,您访问 *(ptr + 0) 和 *(ptr + 1) ...这恰好不是错误的来源,因为这两个语法的意思是一样的,但是使用两种不同的形式是不好的风格,读起来很糟糕,而且容易出错。但是,在一个文件中声明void **ptr,但在另一个文件中声明void *ptr——这不可能是正确的,因为这两个ptr具有相同的语义(它们都指向一个包含两个元素的数组, 一个 tf 和一个 as)。在一个文件中,您有一个函数,该函数接受一个名为 ptr 的参数,但在另一个文件中,您再次传递了一个名为 ptr ... 的变量的 contents,因为这两个 ptr 具有相同的语义,这不一致一定是错误的,显然是取消引用是错误的。删除它,你将传递一个void**,所以这就是 func 的参数。

          代码始终如一,所有错误都会从您的代码中消失。您可以编写 3 年或 30 年的代码,但如果您不学习这些基础知识也没关系。

          【讨论】:

            猜你喜欢
            • 2020-12-14
            • 2021-09-20
            • 2011-10-30
            • 2010-10-08
            • 2021-08-23
            相关资源
            最近更新 更多