C语言 我们必须 malloc 一个结构吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26206667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 11:26:02  来源:igfitidea点击:

Do we have to malloc a struct?

cstructmalloc

提问by Spag Guy

Consider the following code:

考虑以下代码:

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

I have found that I am getting segfaults whenever I try to do anything with NodePtr's fields. E.g.:

我发现每当我尝试对 NodePtr 的字段做任何事情时都会出现段错误。例如:

NodePtr node;
node->ref = 1;

So I allocated some space for the NodePtr, and now it seems to work fine. Why is this? My guess is that since node is just a pointer, it has no memory for its fields.

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

So I tried to initialize the NodePtr:

所以我尝试初始化NodePtr:

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

And well, I got this error:

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

error: expected a}a before a;a token

This boils down to four questions:

这归结为四个问题:

  1. If my guess is incorrect, why doesn't it work if I don't use malloc()?
  2. Why does my initialization not work?
  3. Would initializing a struct offer memory on the stack and solve my problem?
  4. If not, do I have an alternative to having to allocate memory for every struct I use?
  1. 如果我的猜测不正确,为什么不使用 malloc() 就不起作用?
  2. 为什么我的初始化不起作用?
  3. 初始化结构会在堆栈上提供内存并解决我的问题吗?
  4. 如果没有,除了为我使用的每个结构分配内存之外,我还有其他选择吗?

回答by alireza_fn

A structcan be allocated automatically, but you are using a pointer to structwhich will not allocate space for the destination struct. So that's the reason you get segfault.

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

The reason your initialization is incorrect is that you are initializing structmembers, not the structitself. Also you are doing this in a wrong way.

您的初始化不正确的原因是您正在初始化structmembers,而不是它struct本身。此外,您以错误的方式执行此操作。

There are 2 ways for initializing a struct:

有两种初始化 a 的方法struct

  1. Using stack allocated struct:

    struct example {
      int foo;
    };
    int main() {
      struct example e;
      e.foo=1;
    }
    
  2. Using heap allocated structwith help of malloc():

    struct example {
      int foo;
    };
    int main() {
      struct example *e=malloc(sizeof(struct example));
      e->foo=1;
    }
    
  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;
    }
    

Please note that when you are assigning value to a member of a structfrom its pointer (heap allocated struct) you have to use '->' but for the normal struct (the stack allocated one) you have to use '.' .

请注意,当您struct从a的指针(分配的堆struct)为 a 的成员赋值时,您必须使用 ' ->' 但对于普通结构(分配的堆栈),您必须使用 ' .' 。

回答by itdoesntwork

A pointer isn't a struct. It's a number that tells C where the struct is located in memory. Any varible with type NodePtris essentially a number.

指针不是结构。它是一个数字,告诉 C 结构体在内存中的位置。任何具有类型的变量NodePtr本质上都是一个数字。

How does it make sense, then, to set a variable of type NodePtrto a struct? A struct isn't a number!

那么,将类型变量设置NodePtr为结构体有什么意义呢?结构体不是数字!

When you declare it with NodePtr node, it might be set to some undefined value like 0. You can't access that memory, which leads to a segfault. Instead, you locate some memory to use with malloc()and make that variable point there where its fields can be used.

当您使用 声明它时NodePtr node,它可能会被设置为某个未定义的值,例如 0。您无法访问该内存,这会导致段错误。相反,您可以找到一些要使用的内存malloc(),并使该变量指向可以使用其字段的地方。



To respond to potrzebie's comment, it seems to work with strings but that's really just syntactic sugar:

为了回应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

回答by Marco A.

Your assumption is correct: a pointer hasn't memory for the object it is supposed to point on its own, you need to allocate it yourself.

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

Anyway, as juanchopanza noted: you don't need a pointer and a memory allocation if you're dealing with a local object.

无论如何,正如 juanchopanza 指出的:如果您正在处理本地对象,则不需要指针和内存分配。

Both techniques follow:

这两种技术都遵循:

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

The other syntaxes you tried are notcorrect. Not even part of the language.

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