-1

这可能是一个愚蠢的问题,我看到有人问过类似的问题,但我没有得到答案。为什么以下代码会产生:

错误:从类型“struct node_t *”分配给类型“node_t”时类型不兼容</p>

node_t list_array[10];
typedef struct node
{
    int value;
    struct node *next;
    struct node *prev;
} node_t;

node_t* create_node(void)
{
    node_t *np;
    np->next = NULL;
    np->prev = NULL;
    np->value = rand() % 10;
    return np;
}

int main(void)
{
int i;
for(i = 0; i < 10; i++)
{
    list_array[i] = create_node();
}
return 0;
}    
4

6 回答 6

4

将数组变成指针数组以修复错误,因为create_node返回一个指针:

node_t *list_array[10];

请注意,您没有分配任何内存,create_node因此使用np是非法的。尝试:

node_t *np = malloc(sizeof *np);

我想制作一个 node_t 结构数组

在这种情况下,您可以离开 node_t list_array[10] 并且:

  • &list_array[i]作为参数传递给函数
  • 让函数返回 anode_t而不是 anode_t *
于 2013-02-11T10:53:33.597 回答
4

因为一个是结构体,另一个是结构体的指针

create_node()函数返回一个指向节点的指针(malloc()顺便说一句,您确实应该在该函数中使用它),然后您尝试将其分配给数组中的实际结构。

您只需将声明更改为:

node_t *list_array[10];

所以它是一个指针数组而不是一个结构数组。

于 2013-02-11T10:54:39.743 回答
4

因为create_node()返回一个指针,但是list_array[i]是一个实际的实例。您不能在实例上分配指针,它们完全不同。

解决方案通常是将每个节点表示为一个指针,它需要list_array是一个指针数组:

node_t *list_array[10];

然后分配有意义,代码将编译。

但是请注意,代码不会“工作”,因为它取消引用NULL内部的指针create_node()。看来你忘了打电话malloc()

node_t* create_node(void)
{
    node_t *np;
    if((np = malloc(sizeof *np)) != NULL)
    {
        np->next = NULL;
        np->prev = NULL;
        np->value = rand() % 10;
    }
    return np;
}
于 2013-02-11T10:55:00.883 回答
1

这是经典的“指针与实例”混淆。比你的警告更严重的是:

node_t *np;
np->next = NULL;

这将编译,然后是段错误。

由于对指针是什么的误解而产生了混淆。编译时,指针只是一个数字,例如 140734799803888。此数字仅用于定位物理数据块。这是一个内存地址

指针与实例令人困惑,这是您在编程中遇到的第一个概念挑战。所以这里有一个类比:

如果您曾经使用过 GPS,它会告诉您您在哪里(指针),但不会告诉您您是什么(数据)。指针的工作方式相同。如果有人想和你握手,他们不会摇 GPS 坐标(指针)!他们会使用 GPS 坐标来定位您,然后亲自拜访您(数据)并与您握手。这就是指针的工作原理。

因此,在上面的代码中,您声明了一个指针np,但不给它任何位置来跟踪。然后,你问“使用里面的数字np来定位我的数据”(但你还没有设置一个数字np!)特别是,np->next要求使用位置np + someOffset(这是未定义的!)来查找你的物理数据(这是无处可去的) , 并改变它。

这就是为什么你得到一个段错误。

于 2013-02-11T11:59:05.533 回答
0

node_t list_array[10]应该是node_t *list_array[10] 你也有,而不是malloc你的node_t *np

node_t *np = malloc(sizeof(node_t));

于 2013-02-11T10:54:45.193 回答
0

对于这个程序,我认为使用动态存储持续时间 (malloc) 没有意义。如果您希望将所有对象保持在静态存储期间,我会处理 create_node 以支持 memcpy。例如,

#include <string.h>

typedef struct node
{
    int value;
    struct node *next;
    struct node *prev;
} node_t;

int main(void) {
    node_t list_array[10];
    for (int i = 0; i < sizeof (list_array) / sizeof (*list_array); i++) {
        memcpy(list_array + i,
               &(node_t){ .value = rand() % 10,
                          .next = NULL,
                          .prev = NULL },
               sizeof (*list_array));
    }
    return 0;
}
于 2013-02-11T13:52:21.187 回答