为什么编译失败并出现错误:转换为请求的非标量类型

时间:2017-04-28 14:22:46

标签: c structure

程序:

#include <stdio.h>
#include <stdlib.h>
struct s
{
    int a;
    struct x
    {
        int b;
    }*p;
};
int main()
{
    struct s *a;
    a=(struct s *)malloc(sizeof(struct s) * 10);
    a->p=(struct x)malloc(sizeof(struct x));
    return 0;
}

错误: - 在函数&#39; main&#39;:16:41:错误:转换为非标量类型请求a-&gt; p =(struct x)malloc(sizeof(struct x) ); ^

6 个答案:

答案 0 :(得分:2)

在C中,与物理学一样,标量类型只是一个单一的大小。整数类型,浮点类型和指针类型被认为是标量类型。 struct不是标量类型。

这一行

 a->p=(struct x)malloc(sizeof(struct x));

尝试将一个malloc的结果(实际上是一个void*,因此一个标量)转换为非{。{}}的结构,也是一个类型为{a->p的指针。 1}}所以错误信息意味着你的演员会忘记使目标类型成为指针类型的struct s*。即这应该是:

*

实际上,在C中,与C ++相反,你不需要将 a->p=(struct x*)malloc(sizeof(struct x)); 转换为其他指针类型,所以最好只写

void*

这样做的主要原因是,如果您忘记包含 a->p=malloc(sizeof(struct x)); 的原型stdlib.h来自malloc,编译器会假定malloc返回int如果指针不能表示为int,则会发生灾难。例如,现代64位编译器通常具有32位int和64位指针。由于您忘记了malloc

,因此将编译器置于静音状态时,编译器假定int的警告会返回stdlib.h

最后一项改进:即使某个对象尚不存在,您也可以sizeof这样做

a->p=malloc(sizeof *(a->p));

编译器通常知道a-&gt; p指向的东西的大小,因此只要知道大小,就将sizeof设置为正确的数字(参见异常的“不完整类型”)。现在,您可以修改a->p的类型,而无需修复所有malloc

答案 1 :(得分:0)

为避免类型不匹配,分配应遵循

的规范方式
a = malloc(10 * sizeof(*a));
a->p = malloc(1 * sizeof(*a->p));

即。始终引用sizeof中分配给的变量。注意这是多么短暂。 请注意当a的类型发生变化时,这会自动适应。您甚至可以将括号放在sizeof操作数周围,乘以1。

答案 2 :(得分:0)

如评论中所述,您尝试将struct x(从void *投放)分配给struct x *。您不能指定指针的非指针。

您可以使用正确的演员来避免这种情况:

a->p=(struct x *)malloc(sizeof(struct x));

或者更好的是完全删除强制转换,因为你可以在void *和任何非函数指针之间自由地进行转换:

a=malloc(sizeof(struct s) * 10);
a->p=malloc(sizeof(struct x));

答案 3 :(得分:0)

缺少星号。如果确实需要类型转换,则声明

a->p=(struct x)malloc(sizeof(struct x));   // struct x is not a pointer

实际应该是

a->p=(struct x *)malloc(sizeof(struct x));

当然,正如其他人在评论中所说,类型转换是不可取的。建议不要在malloc()的参数中命名为sizeof的类型,以便函数中的两个语句为

a = malloc(sizeof(*a) * 10);
a->p = malloc(sizeof(*(a->p)));

建议在使用malloc()之前检查每次调用的结果,因为malloc()在失败时会返回NULL

注意:如果您的C编译器实际上是C ++编译器,则需要转换malloc()的结果。但是,在标准C中,不需要转换,并且主动不鼓励。

答案 4 :(得分:0)

你有一个简单的拼写错误,源于在作业 1 右侧投射malloc的不可取的做法。

此外,您应该检查malloc的返回值,尤其是在使用指向成员运算符->的指针之前。

所以我宁愿看到

的内容
if (a = malloc(sizeof(*a) * 10)){
    if (a->p = malloc(sizeof(*(a->p)))){
        // Everything is allocated.
        // ToDo - code here
        free(a->p);
    }
    free(a);
}

(请注意,在评估sizeof(*(a->p))时,编译器必须实际执行任何解除引用,因此a有效或{{1}无关紧要是有效的。)

1 请参阅Do I cast the result of malloc?

答案 5 :(得分:-1)

你应该试试 a-&gt; p =(struct x *)malloc(sizeof(struct x));