嘿,我收到了这个错误:
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
答案 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);
有两点需要注意。首先,抛弃演员表达。 malloc
,calloc
和realloc
都返回void *
,可以将其分配给任何对象指针类型,而无需使用强制转换 1 。事实上,如果您忘记在范围 2 中包含stdlib.h
或者没有malloc
的声明,则演员的存在可能会掩盖错误。
其次,请注意我使用表达式*new_node
作为sizeof
的参数,而不是(struct key)
。 sizeof
不评估它的运算符(除非它是变量数组类型,这不是);它只是计算表达式的类型。由于表达式*new_node
的类型为struct key
,sizeof
将返回存储该对象的正确字节数。如果您的代码结构类似于
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;
并期望a
和b
成为指针(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)
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;”而不是星号“*”。星号取消引用指针,&符号为您提供值的指针。