考虑以下代码:
struct Node {
void* data;
int ref;
struct Node* next;
};
typedef struct Node* NodePtr;
我发现,每当我尝试使用NodePtr的字段做任何事情时,我都会遇到segfault。例如:
NodePtr node;
node->ref = 1;
所以我为NodePtr分配了一些空间,现在它似乎工作得很好。为什么会这样?我的猜测是,由于节点只是一个指针,所以它并没有字段的内存。
所以我尝试初始化NodePtr:
NodePtr node = {
node->data = 0;
node->next = NULL;
node->ref = 0;
};
好吧,我得到了这个错误:
error: expected â}â before â;â token
这归结为四个问题:
- 如果我的猜测不正确,为什么我不使用malloc()就不起作用
- 为什么我的初始化不起作用
- 初始化结构会在堆栈上提供内存并解决我的问题吗
- 如果没有,除了为我使用的每个结构分配内存之外,我还有其他选择吗
struct
可以自动分配,但您使用的是指向struct
的指针,该指针不会为目标struct
分配空间。所以这就是你出现segfault的原因。
初始化不正确的原因是您正在初始化struct
成员,而不是struct
本身。而且你这样做的方式不对。
初始化struct
:有两种方法
-
使用堆栈分配的
struct
:struct example { int foo; }; int main() { struct example e; e.foo=1; }
-
借助
malloc()
:使用堆分配的struct
struct example { int foo; }; int main() { struct example *e=malloc(sizeof(struct example)); e->foo=1; }
请注意,当您从struct
的指针(堆分配的struct
)为其成员赋值时,必须使用"->
",但对于普通结构(堆栈分配的结构),必须使用".
"。
您的假设是正确的:指针没有内存用于它应该自己指向的对象,您需要自己分配它。
不管怎样,正如juancapanza所指出的:如果您处理的是本地对象,则不需要指针和内存分配。
这两种技术都遵循:
typedef struct Node {
void* data;
int ref;
struct Node* next;
} Node;
typedef struct Node* NodePtr;
int main() {
NodePtr node = (NodePtr)malloc(sizeof(Node));
node->data = 0;
node->next = 0;
node->ref = 42;
printf("%d", node->ref);
Node obj = {0,42,0}; // this is not on the heap
printf("%d", obj.ref);
您尝试的其他语法不正确。甚至不是语言的一部分。
指针不是结构。这是一个数字,告诉C结构在内存中的位置。任何类型为NodePtr
的变量本质上都是一个数字。
那么,将NodePtr
类型的变量设置为结构有什么意义呢?结构不是数字!
当您用NodePtr node
声明它时,它可能被设置为一些未定义的值,如0。您无法访问该内存,这将导致segfault。相反,您可以找到一些与malloc()
一起使用的内存,并将该变量指向可以使用其字段的位置。
为了回应potrzebie的评论,它似乎可以使用字符串,但这实际上只是语法糖:
#include <stdio.h>
int main() {
char *a = "Does this make sense?";
printf("%dn", a); // %u is the correct one, but this is for illustrational purposes
return 0;
}
> test.exe
4214884