得到C错误:转换为请求的非标量类型

时间:2012-01-26 00:07:23

标签: c pointers struct

嘿,我收到了这个错误:

error: conversion to non-scalar type requested

以下是我的结构:

typedef struct value_t value;

struct value{
   void* x;
   int y;
   value* next;
   value* prev;
};

typedef struct key_t key;

struct key{
   int x;
   value * values;
   key* next;
   key* prev;
};

以下是给我提问的代码:

struct key new_node = (struct key) calloc(1, sizeof(struct key));
struct key* curr_node = head;

new_node.key = new_key;

struct value head_value = (struct value) calloc(1, sizeof(struct value))

我不想在结构上使用calloc吗?此外,我有一个我已经创建的结构,然后我想将其设置为相同结构类型的指针,但得到一个错误。这是我正在做的一个例子:

struct value x;
struct value* y = *x;

这给了我这个错误

error: invalid type argument of ‘unary *’

当我做y = x时,我收到此警告:

warning: assignment from incompatible pointer type

6 个答案:

答案 0 :(得分:13)

您正在尝试将指针表达式(malloc(的返回类型)和friends为void *)分配给结构类型(struct new_node)。那是胡说八道。另外:不需要演员(可能很危险,因为它可以隐藏错误)

struct key *new_node = calloc(1, sizeof *new_node);

与其他malloc()行相同的问题:

struct value *head_value = calloc(1, sizeof *head_value);

更多错误:您省略了'struct'关键字(在C ++中允许,但在C中是无意义的):

struct key{
   int x;
   struct value *values;
   struct key *next;
   struct key *prev;
};

更新:使用struct的结构和指针。

struct key the_struct;
struct key other_struct;
struct key *the_pointer;

the_pointer = &other_struct; // a pointer should point to something

the_struct.x = 42;
the_pointer->x = the_struct.x; 

 /* a->b can be seen as shorthand for (*a).b :: */
(*thepointer).x = the_struct.x;

/* and for the pointer members :: */

the_struct.next = the_pointer;
the_pointer->next = malloc (sizeof *the_pointer->next);

答案 1 :(得分:3)

我认为你没有正确理解typedef s。

使用typedef进行便捷命名的常见习惯是:

struct foo {
    int something;
};

typedef struct foo foo_t;

然后您使用foo_t类型而不是不太方便的struct foo

为方便起见,您可以将struct声明和typedef合并为一个块:

typedef struct {
    int something;
} foo_t;

这就像上面一样定义了foo_t

typedef行上的最后标记是您要分配的名称。我不知道你写的代码实际上对你的命名空间做了什么,但我怀疑它是你想要的。

现在,至于代码本身:calloc会返回一个指针,这意味着两者您的演员阵容,您的存储类型应为struct key*(或者,如果您修复了命名,key_t)。正确的行是struct key* new_node = (struct key*)calloc(1, sizeof(struct key));

对于您的第二个独立问题,最后一行应为struct value* y = &x;。您希望y存储 x地址,而不是地址x 处的内容。错误消息表明这一点 - 您正在滥用一元星型运算符尝试取消引用非指针变量。

答案 2 :(得分:2)

struct key new_node = (struct key) calloc(1, sizeof(struct key)); 

calloc返回一个指针值(void *),您尝试将其转换并分配给聚合(IOW,非标量)类型(struct key)。要解决此问题,请将new_node的类型更改为struct key *并重写您的分配,如下所示:

struct key *new_node = calloc(1, sizeof *new_node);

有两点需要注意。首先,抛弃演员表达。 malloccallocrealloc都返回void *,可以将其分配给任何对象指针类型,而无需使用强制转换 1 。事实上,如果您忘记在范围 2 中包含stdlib.h或者没有malloc的声明,则演员的存在可能会掩盖错误。

其次,请注意我使用表达式*new_node作为sizeof的参数,而不是(struct key)sizeof不评估它的运算符(除非它是变量数组类型,这不是);它只是计算表达式的类型。由于表达式*new_node的类型为struct keysizeof将返回存储该对象的正确字节数。如果您的代码结构类似于

,它可以节省一些维护麻烦
T *foo;
... // more than a few lines of code
foo = malloc(sizeof (T))

并且您在声明中更改了foo的类型,但忘记更新malloc调用。

此外,您还不清楚要使用typedef和struct定义完成什么。代码

typedef struct value_t value;  

struct value{
   void* x;
   int y;
   value* next;
   value* prev;
};

没有做你想象的那样。您正在创建一个typedef名称value,它是尚未定义的类型struct value_t的同义词。此value类型与您稍后创建的struct value类型不同(typedef名称和结构标记位于不同的名称空间中)。重写你的结构以遵循这个模型:

struct value_t {
  void *x;
  int y;
  struct value_t *next;
  struct value_t *prev;
};

typedef struct value_t value;

此外,如果编写声明以使*与声明符相关联,而不是类型说明符 3 ,则生活会更容易。像T* p这样的声明被解析为好像是T (*p)。这样可以避免编写int* a, b;并期望ab成为指针(b只是常规int)的尴尬。

<小时/> 1 - 这是C和C ++不同的一个领域; C ++ 允许void *和其他对象指针类型之间的隐式转换,因此如果将其编译为C ++代码,则在编译时会出现错误。此外,在采用1989标准之前,*alloc函数返回char *,因此在那些日期,如果您指定了不同的指针类型,则需要 。如果您正在使用非常旧的系统,这应该只是一个问题。

2 - 直到1999年的标准,如果编译器看到没有前面声明的函数调用,它假定函数返回int(这就是为什么你偶尔会看到例子像

 main()
 {
   ...
 }

在一些教程中;隐式键入main以返回int。从C99开始,不再允许这样做。因此,如果您忘记包含stdlib.h并调用calloc(并且您没有编译为C99),编译器将假定该函数返回int并相应地生成机器代码。如果您关闭演员表,编译器将发出一个诊断,表明您试图为指针分配int值,这是不允许的。如果你保留了强制转换,代码将被编译,但指针值可能在运行时被激活(指向int的指针的转换再次返回指针并不保证有意义)。

3 - 有一些罕见的实例,仅限于C ++,其中T* p样式可以使代码更清晰,但总的来说,你最好遵循{{ 1}}风格。是的,这是一个个人观点,但是有一个非常微不足道的经验支持。

答案 3 :(得分:1)

calloc(3)pointer返回到它分配的内存。

struct key new_node = (struct key) calloc(1, sizeof(struct key));

应该是

struct key* new_node = calloc(1, sizeof(struct key));

答案 4 :(得分:1)

您不应该指向非指针变量的指针。将new_node更改为指针。

另外,要使用变量的地址,您需要&,而不是*,因此请将其更改为struct value* y = &x;

编辑:你的typedef也是错误的。扭转他们。

答案 5 :(得分:0)

对于第二个问题,你想使用&符号“&amp;”而不是星号“*”。星号取消引用指针,&符号为您提供值的指针。