无法在C上分配动态数组

无法在C上分配动态数组,c,malloc,C,Malloc,我试图在C上创建一个图形结构,但我遇到了一些问题。首先,我得到两个编译错误: main.c:18:19: error: member reference type 'node' is not a pointer; did you mean to use '.'? graph[index]->start = NULL; ~~~~~~~~~~~~^~ . main.c:18:27: error: expression is

我试图在C上创建一个图形结构,但我遇到了一些问题。首先,我得到两个编译错误:

main.c:18:19: error: member reference type 'node' is not a
      pointer; did you mean to use '.'?
      graph[index]->start = NULL;
      ~~~~~~~~~~~~^~
                  .
main.c:18:27: error: expression is not assignable
      graph[index]->start = NULL;
      ~~~~~~~~~~~~~~~~~~~ ^
2 errors generated.
compiler exit status 1
我不知道我做错了什么。我试图创建一个节点数组*,但由于某种原因,编译器无法将其识别为指针。就像malloc不工作一样。此外,我无法访问edge*字段,因为这就像节点数组*不存在一样

#include <stdio.h>
#include <stdlib.h>

#define maxNodes 4

typedef struct edge {
    int target;
    struct edge* next;
} edge;

typedef struct {
    edge* start;
} node;

void initializeGraph(node* graph) {
    graph = (node *) malloc(maxNodes * sizeof(node));
    for(int index = 0; index < maxNodes; index++) {
      graph[index]->start = NULL;
    }
}

int main(void) {
    node test;
    initializeGraph(&test);
}
#包括
#包括
#定义maxNodes 4
typedef结构边缘{
int目标;
结构边缘*下一步;
}边缘;
类型定义结构{
边缘*开始;
}节点;
无效初始化图(节点*图形){
图=(节点*)malloc(maxNodes*sizeof(节点));
对于(int index=0;indexstart=NULL;
}
}
内部主(空){
节点测试;
初始化图(和测试);
}

我正在尝试初始化我的结构。非常感谢您的帮助。

数组索引操作符
[]
隐式取消引用指针。语法
a[b]
*(a+b)
完全相同

这意味着
图形[索引]
具有类型
节点
,而不是
节点*
。因此,请使用
而不是错误消息所示的
->

graph[index].start = NULL;

在简短的示例代码中有大量问题。至于您的错误,@dbush的回答中包含了这一点,
[…]
作为指针的解引用,使
'。
(点)运算符正确,而不是
->
箭头运算符

接下来,您不能在
main()
中声明具有静态存储持续时间的节点,并在函数中传递其分配地址。当您声明
节点测试时堆栈上已提供所有存储。然后不能将该地址传递给函数并为该结构分配额外内存

如果希望有多个节点,则可以在
main()
中声明具有静态存储持续时间的数组,或者必须在
main()
中声明指针并在函数中分配。要使该分配在
main()
中可见,如我的评论中所述,您可以(1)使返回类型
节点*
并返回指向分配给调用方的块的指针,或者(2)使参数
节点**
并将指针的地址作为参数传递

综上所述,选择上述选项(1),您可以:

#include <stdio.h>
#include <stdlib.h>

#define maxNodes 4

typedef struct edge {
    int target;
    struct edge* next;
} edge;

typedef struct {
    edge* start;
} node;

node *initializeGraph (void) {
    node *graph = malloc(maxNodes * sizeof *graph);
    if (!graph)
        return NULL;
    for (int index = 0; index < maxNodes; index++) {
        graph[index].start = NULL;
    }
    return graph;
}

int main (void) {

    node *test = initializeGraph();

    if (!test)
        fputs ("error: initialization failed.\n", stderr);
    else
        puts ("initialization succeeded");
}
int main (void) {

    node *test = initializeGraph();

    if (!test)
        fputs ("error: initialization failed.\n", stderr);
    else
        puts ("initialization succeeded");

    for (int i = 0; i < maxNodes; i++)
        test[i].start->target = i;

    puts ("targets filled");
}
为每个测试分配[i]。开始

$ ./bin/graphinit
initialization succeeded
$ ./bin/graphinit
initialization succeeded
targets filled
在使用任何
开始
指针之前,必须为
结构边缘
分配存储,并将该内存块的开始地址分配给每个
测试[i]。开始
指针。您可以在相同的
initializeGraph()
函数中通过分配当前设置指针的位置
NULL
,例如

node *initializeGraph (void)
{
    node *graph = malloc(maxNodes * sizeof *graph);
    if (!graph)
        return NULL;
    for (int index = 0; index < maxNodes; index++) {
        graph[index].start = malloc (sizeof *graph[index].start);
        if (!graph[index].start)
            return NULL;
    }
    return graph;
}
示例使用/输出

$ ./bin/graphinit
initialization succeeded
$ ./bin/graphinit
initialization succeeded
targets filled
(不要忘记在不再需要时释放分配的内存)


仔细检查一下,如果您还有其他问题,请告诉我。

您认为
图形[索引]
的类型是什么?你知道
->
之间的区别是什么吗?你用
无效初始化图(节点*图)
传递指针
图的副本。函数中的分配永远不会在调用函数中看到。您有两个选项(1)使返回类型为
节点*
并返回一个指向分配给调用者的块的指针,或(2)使参数
节点**
并传递地址。另请注意,
[…]
起到取消引用的作用,因此
图形[index].start
是合适的。并且,您不能在
main()
中声明具有静态存储持续时间的节点,并在函数中传递其分配地址。(坏事会发生)。当您声明
节点测试时堆栈上已提供所有存储。您可以声明一个指针并分配(以上面的注释为准),如果您想拥有多个节点,则需要这样做。我已将->更改为。并修复了静态存储持续时间的问题,但我仍然不能使用edge*测试;测试->目标=400;图[3]。开始=测试//我遇到了分段错误,就像我以前没有分配内存一样。。。。有什么想法吗?当您为
test
(如下面的答案所示)分配存储时,您为4
struct节点
分配存储。每个指针都包含一个名为
start
的类型为
stuct edge
的未初始化指针。您可以像在函数中那样设置
start
指针
NULL
,但在分配存储器并将该内存块的起始地址分配给
test[i]之前,您不能以任何其他方式使用它们。然后您可以使用
test[i]。启动
。我将->更改为。它成功了。我正在打印数组,它为每个成员返回0。对吗?谢谢你帮我。我理解了你提出的所有观点,现在代码正在运行。我不知道C有这么多的细节需要关心。我会更小心的。你必须戴上你的会计帽,对你使用或分配的每个字节的内存进行说明。请稍等,我将给出一个示例,演示如何分配和填充
目标。我会很感激的!点击刷新——我在最后添加了这个例子。基本上,每当我想使用指针时,我必须先用malloc分配内存,然后给这个内存块分配一个初始地址值。是这样吗?我已经习惯了Java,所有的内存都是由语言来处理的,如果这听起来像是个愚蠢的问题,我很抱歉。