无法在C上分配动态数组
我试图在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
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
(如下面的答案所示)分配存储时,您为4struct节点
分配存储。每个指针都包含一个名为start
的类型为stuct edge
的未初始化指针。您可以像在函数中那样设置start
指针NULL
,但在分配存储器并将该内存块的起始地址分配给test[i]之前,您不能以任何其他方式使用它们。然后您可以使用test[i]。启动。我将->更改为。它成功了。我正在打印数组,它为每个成员返回0。对吗?谢谢你帮我。我理解了你提出的所有观点,现在代码正在运行。我不知道C有这么多的细节需要关心。我会更小心的。你必须戴上你的会计帽,对你使用或分配的每个字节的内存进行说明。请稍等,我将给出一个示例,演示如何分配和填充目标。我会很感激的!点击刷新——我在最后添加了这个例子。基本上,每当我想使用指针时,我必须先用malloc分配内存,然后给这个内存块分配一个初始地址值。是这样吗?我已经习惯了Java,所有的内存都是由语言来处理的,如果这听起来像是个愚蠢的问题,我很抱歉。