我们必须malloc一个结构吗?

时间:2014-10-05 20:01:40

标签: c struct malloc

请考虑以下代码:

struct Node {
    void* data;
    int ref;
    struct Node* next;
};
typedef struct Node* NodePtr;

我发现每当我尝试使用NodePtr的字段做任何事情时,我都会遇到段错误。 E.g:

NodePtr node;
node->ref = 1;

所以我为NodePtr分配了一些空间,现在它似乎工作正常。为什么是这样?我的猜测是,由于节点只是一个指针,它的字段没有内存。

所以我尝试初始化NodePtr:

NodePtr node = {
    node->data = 0;
    node->next = NULL;
    node->ref = 0;
};

好吧,我收到了这个错误:

error: expected â}â before â;â token

这归结为四个问题:

  1. 如果我的猜测不正确,如果我不使用malloc(),为什么它不起作用?
  2. 为什么我的初始化不起作用?
  3. 初始化一个struct会在堆栈上提供内存并解决我的问题吗?
  4. 如果没有,我是否可以为我使用的每个结构分配内存?

3 个答案:

答案 0 :(得分:20)

可以自动分配struct,但您使用的指针struct不会为目标struct分配空间。这就是你遇到段错误的原因。

初始化不正确的原因是您正在初始化struct 成员,而不是struct本身。你也是以错误的方式做这件事。

有两种方法可以初始化struct

  1. 使用堆叠分配struct

    struct example {
      int foo;
    };
    int main() {
      struct example e;
      e.foo=1;
    }
    
  2. struct的帮助下使用堆分配malloc()

    struct example {
      int foo;
    };
    int main() {
      struct example *e=malloc(sizeof(struct example));
      e->foo=1;
    }
    
  3. 请注意,当您从其指针(堆分配struct)为struct的成员分配值时,您必须使用“->”但对于正常结构(堆栈分配一个)你必须使用'.'。

答案 1 :(得分:2)

指针不是结构。它是一个数字告诉C结构位于内存中的位置。类型NodePtr的任何变量基本上都是数字。

那么,如何将NodePtr类型的变量设置为结构?结构不是数字!

当您使用NodePtr node声明它时,可能会将其设置为某个未定义的值,如0.您无法访问该内存,从而导致段错误。相反,您找到了一些用于malloc()的内存,并将该变量指向那里可以使用其字段的位置。


为了回应potrzebie的评论,它似乎与字符串一起使用,但这实际上只是语法糖:

#include <stdio.h>

int main() {
  char *a = "Does this make sense?";
  printf("%d\n", a); // %u is the correct one, but this is for illustrational purposes

  return 0;
}


> test.exe
4214884

答案 2 :(得分:1)

你的假设是正确的:一个指针没有自己应该指向的对象的内存,你需要自己分配它。

无论如何,正如juanchopanza所说:如果你正在处理本地对象,你不需要指针和内存分配。

这两种技术都遵循:

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);

您尝试的其他语法正确。甚至不是语言的一部分。