【问题标题】:Do we have to malloc a struct?我们必须 malloc 一个结构吗?
【发布时间】:2014-10-05 20:01:39
【问题描述】:

考虑以下代码:

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

我发现每当我尝试对 NodePtr 的字段进行任何操作时都会出现段错误。例如:

NodePtr node;
node->ref = 1;

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

所以我尝试初始化NodePtr:

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

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

error: expected â}â before â;â token

这归结为四个问题:

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

【问题讨论】:

  • 你不需要malloc。例如,struct Node n = {NULL, 42, NULL};。你只是到处都有语法错误。
  • 创建非指针对象时不需要分配内存。
  • 您的 NodePtr 初始化甚至不是正确的 C 语法,这不可能是您尝试过的代码。
  • 请一次只问一个问题,并投入更多精力来阅读内容,区分不同的概念,在启用编译器的所有警告的情况下先进行测试...
  • @Jens Gustedt,我对语法错误负责,但我认为这些是您对某人的强烈假设。我注意到语法错误,因为它是我使用 malloc 解决方案的一部分。

标签: c struct malloc


【解决方案1】:

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

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

有两种方法可以初始化struct

  1. 使用分配的堆栈struct:

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

    struct example {
      int foo;
    };
    int main() {
      struct example *e=malloc(sizeof(struct example));
      e->foo=1;
    }
    

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

【讨论】:

    【解决方案2】:

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

    无论如何,正如 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);
    

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

    【讨论】:

      【解决方案3】:

      指针不是结构。这是一个告诉 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
      

      【讨论】:

      • 应该是有道理的,你可以用字符串来做。
      • @potrzebie char *x = "..."?那是语法糖,它仍然是一个数字,字符串存储在其他地方。这是投反对票的原因吗(如果是你)?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-02
      • 1970-01-01
      • 2021-07-08
      • 2014-12-21
      • 1970-01-01
      • 2015-02-12
      相关资源
      最近更新 更多