C struct和malloc问题(C)

时间:2011-01-22 15:09:56

标签: c struct malloc

令人惊讶的是,即使是最小的程序也会在C中造成如此多的麻烦。

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

typedef struct node {
    int value;
    struct node *leftChild;
    struct node *rightChild;
} node;

typedef struct tree {
    int numNodes;
    struct node** nodes;
} tree;

tree *initTree() {
    tree* tree = (tree*) malloc(sizeof(tree));
    node *node = (node*) malloc(sizeof(node));
    tree->nodes[0] = node;
    return tree;
}

int main() {
    return 0;
}

编译器说:

main.c: In function 'initTree':
main.c:17: error: expected expression before ')' token 
main.c:18: error: expected expression before ')' token

你能帮忙吗?

8 个答案:

答案 0 :(得分:13)

您使用了两个名为treenode的变量,但您还将typedef编辑为treenode

更改变量名称:

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

typedef struct node {
    int value;
    struct node *leftChild;
    struct node *rightChild;
} node;

typedef struct tree {
    int numNodes;
    struct node** nodes;
} tree;

tree *initTree() {
   /* in C code (not C++), don't have to cast malloc's return pointer, it's implicitly converted from void* */
   tree* atree = malloc(sizeof(tree)); /* different names for variables */
   node* anode = malloc(sizeof(node));
   atree->nodes[0] = anode;
   return atree;
}

int main() {
    return 0;
}

答案 1 :(得分:5)

treenode是您的案例类型名称,不应在以后用作变量名称。

tree *initTree() {
    tree *myTree = (tree*) malloc(sizeof(tree));
    node *myNode = (node*) malloc(sizeof(node));
    myTree->nodes[0] = myNode;
    return myTree;
}

答案 2 :(得分:3)

(tree*)(node*)更改为(struct tree*)(struct node*)。你不能只说tree,因为那也是一个变量。

答案 3 :(得分:2)

按如下方式更改initTree的主体:

tree* myTree = (tree *)malloc(sizeof(tree));
node *myNode = (node *)malloc(sizeof(node));
myTree->nodes[0] = myNode;
return myTree;

答案 4 :(得分:1)

不要将typedef'ed名称用作变量名,并且不需要在C中强制转换malloc();

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

typedef struct node {
    int value;
    struct node *leftChild;
    struct node *rightChild;
} node;

typedef struct tree {
    int numNodes;
    struct node** nodes;
} tree;

tree *initTree() {
    tree->nodes[0] = malloc(sizeof(node));
    return malloc(sizeof(tree));
}

int main() {
    return 0;
}

答案 5 :(得分:0)

我认为Mehrdad的解释非常重要。

在C代码中,您定义一个与结构名称相同的变量(例如“node node;”)并不罕见。也许这不是一个好的风格;它常见于,例如, linux内核,代码。

原始代码中的真正问题是编译器不知道如何解释“(tree *)malloc”中的“tree”。根据编译错误,它显然被解释为变量。

答案 6 :(得分:0)

除了原始问题之外,这段代码,即使是正确的形式也不会起作用,这仅仅是因为tree::nodes(对于C ++表示法而言)作为指针的指针不会指向任何东西在tree已经被malloced之后立即使用。所以tree->nodes[0]在普通指针的情况下基本上与*(tree->nodes)相同,不能被解除引用。无论如何,这对于树来说是一个非常奇怪的头,但是你应该至少分配一个node*来初始化指向指针的指针:

tree *initTree() {
   /* in C code (not C++), don't have to cast malloc's return pointer, it's implicitly converted from void* */
   tree* atree = malloc(sizeof(struct tree)); /* different names for variables */

   /* ... */

   /* allocate space for numNodes node*, yet numNodes needs to be set to something beforehand */
   atree->nodes = malloc(sizeof(struct node*) * atree->numNodes);

   node* anode = malloc(sizeof(struct node));
   atree->nodes[0] = anode;
   return atree;
}

答案 7 :(得分:0)

有趣的是,如果您只是将分配编写为:

,它会干净地编译
tree *tree = malloc( sizeof *tree );

使用“sizeof variable”通常被认为是更好的风格 而不是“sizeof(type)”,在这种情况下是风格 约定解决了语法错误。我个人认为 这个例子是一个很好的案例,展示了为什么要进行类型转换 通常是一个坏主意,因为如果代码更少混淆 写成:

struct tree *tree = malloc( sizeof *tree );