【问题标题】:Initializing structures with dynamically allocated memory使用动态分配的内存初始化结构
【发布时间】:2014-04-22 01:08:10
【问题描述】:

我很难弄清楚如何动态分配内存,然后用该内存初始化一个结构。我正在尝试制作一棵二叉树,然后将孩子设置为 NULL 作为他们的“单词”,这是我可以测试 NULL 并根据需要插入更多节点。这是我目前所拥有的。

#include <stdio.h>
#include <stdlib.h>

struct node{
   char* word;
   int count;
   struct node* leftchild;
   struct node* rightchild;
};

int main(void){
   struct node *rootnode=malloc(sizeof(struct node));
   scanf("%s ",rootnode.word);
   rootnode.count=countchars(rootnode.word);/*haven't written this func yet*/

   rootnode.leftchild=malloc(sizeof(struct node));
   struct node* leftchild = rootnode.leftchild;
   rootnode.leftchild.word=NULL;

   rootnode.rightchild=malloc(sizeof(struct node));
   struct node* rightchild = rootnode.rightchild;
   rootnode.rightchild.word=NULL;
}

【问题讨论】:

  • 刚开始,您需要在需要时分配用于“word”的缓冲区。
  • 接下来,通常的做法只是将子指针设置为NULL,表示不存在。
  • countchars 的正确拼写实际上是strlen(你还需要包含&lt;string.h&gt; 标头)。
  • 带有尾随空格的格式字符串"%s " 用于交互式输入是危险的。在您键入以下内容之前,它不会返回:(1) 可选的空白字符串,(2) 一个或多个非空白字符的字符串,(3) 一个或多个空白字符的字符串,后跟(4) 非空白字符。令人惊讶的是(4),但在遇到非空白字符之前,它不知道它是否完成了处理(3)。这种行为通常不是您想要的。如果输入严格来自文件是可以的,但大多数时候不是终端输入。
  • 您需要在读取输入之前为rootnode.word分配空间,或者将输入读入缓冲区,然后为缓冲区的副本分配空间。您还应该检查malloc() 的结果,以确保您不会取消引用空指针。而且,正如 DrC 指出的那样,您应该简单地设置 rootnode.leftchild = NULL;rootnode.rightchild = NULL;,而不是使用空的 word 指针分配完整的结构。除此之外,它大大简化了将第二个和后续单词添加到列表中的过程。

标签: c pointers struct c89


【解决方案1】:

您的以下逻辑不正确:

struct node *rootnode=malloc(sizeof(struct node));
scanf("%s ",rootnode.word);
rootnode.count=countchars(rootnode.word);/*haven't written this func yet*/

在上面的代码中,你已经为 struct 节点分配了内存。现在 wordchar 类型的指针。到目前为止,您已经分配了可以将地址存储到此变量中的内存。

现在您需要分配内存以复制到此特定变量中。您需要在此处查找或定义字符串的最大长度。举个例子(100)

rootnode.word = malloc(100*sizeof(char));
// Now you can use this memory further in your program.

顺便说一句,您还需要编写逻辑来释放内存。

【讨论】:

  • 次要评论 - sizeof(char) 绝对等于 1。
【解决方案2】:

对于初学者,您需要在需要时分配用于“单词”的缓冲区。接下来,通常的做法就是将子指针设置为NULL,表示不存在。

所以

node.count=strlen(string); /* hope this is what you want, if not use strlen(string on next line) */
node.word = malloc(node.count+1);
strcpy(node.word, string);
node.leftChild = node.rightChild = NULL;

【讨论】:

    【解决方案3】:

    struct node * 是指针类型。要访问其值,您需要取消引用它们。以下显示了您可能一直在追求的目标:

    typedef struct node_t{
        char* word;
        int count;
        struct node_t* leftchild;
        struct node_t* rightchild;
    } node;
    
    int main(void){
        node *rootnode = (node*)malloc(sizeof(node));
        //scanf("%s ", rootnode.word);
        //rootnode.count = countchars(rootnode.word);/*haven't written this func yet*/
        rootnode->leftchild = (node*)malloc(sizeof(node));
    
        node* leftchild = rootnode->leftchild;
        leftchild->word = NULL;
        rootnode->rightchild = (node*)malloc(sizeof(node));
    
        node* rightchild = rootnode->rightchild;
        rightchild->word = NULL;
        return 0;
    }
    

    请注意,scanf 行已被注释 - 您需要为单词缓冲区分配空间,然后才能读入它。我把它作为练习留给你:)

    【讨论】:

    • 感谢这真的为我清除了一切。我遇到的主要问题之一是 rootnode.leftchild 与 rootnode->leftchild 不同。我只是把它写成 (*rootnode).leftchild
    • 使用(*somePointer). 与使用somePointer-&gt; 相同。后者是语法糖,使阅读代码更容易。
    猜你喜欢
    • 2015-07-23
    • 1970-01-01
    • 2015-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 2012-01-30
    • 1970-01-01
    相关资源
    最近更新 更多