C struct and malloc problem (C)

2019-04-09 12:58发布

It's amazing how even the littlest program can cause so much trouble in 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;
}

The compiler says:

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

Can you please help?

标签: c struct malloc
8条回答
Evening l夕情丶
2楼-- · 2019-04-09 13:05

Don't use typedef'ed names as variable names, and there is not need to cast malloc(); in 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->nodes[0] = malloc(sizeof(node));
    return malloc(sizeof(tree));
}

int main() {
    return 0;
}
查看更多
我只想做你的唯一
3楼-- · 2019-04-09 13:08

Change the body of initTree as follows:

tree* myTree = (tree *)malloc(sizeof(tree));
node *myNode = (node *)malloc(sizeof(node));
myTree->nodes[0] = myNode;
return myTree;
查看更多
女痞
4楼-- · 2019-04-09 13:08

Interestingly, it does compile cleanly if you simply write the allocations as:

tree *tree = malloc( sizeof *tree );

It is often considered better style to use "sizeof variable" rather than "sizeof( type )", and in this case the stylistic convention resolves the syntax error. Personally, I think this example is a good case demonstrating why typecasts are generally a bad idea, as the code is much less obfuscated if written:

struct tree *tree = malloc( sizeof *tree );
查看更多
We Are One
5楼-- · 2019-04-09 13:12

You're using two variables named tree and node, but you also have structs typedefed as tree and node.

Change your variable names:

#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;
}
查看更多
走好不送
6楼-- · 2019-04-09 13:21

Apart from the original question, this code, even in it's correct forms will not work, simply due to the fact that tree::nodes (sorry for the C++ notation) as a pointer to a pointer will not point to anything usefull right after a tree as been malloced. So tree->nodes[0] which in the case of ordinary pointers is essentially the same like *(tree->nodes), can't be dereferenced. This is a very strange head for a tree anyway, but you should at least allocate a single node* to initialize that pointer to pointer:

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;
}
查看更多
你好瞎i
7楼-- · 2019-04-09 13:22

tree and node is your case are type names and should not be used as variable names later on.

tree *initTree() {
    tree *myTree = (tree*) malloc(sizeof(tree));
    node *myNode = (node*) malloc(sizeof(node));
    myTree->nodes[0] = myNode;
    return myTree;
}
查看更多
登录 后发表回答