C结构和malloc问题(C)

C结构和malloc问题(C),c,struct,malloc,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** node

令人惊讶的是,即使是最小的程序也能在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;
}

您能帮忙吗?

(树*)
(节点*)
更改为
(结构树*)
(结构节点*)
。您不能只说
,因为它也是一个变量。

节点
都是类型名称,以后不应用作变量名称

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

您正在使用名为
tree
node
的两个变量,但是您还将结构
typedef
ed设置为
tree
node

更改变量名称:

#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;
}
#包括
#包括
类型定义结构节点{
int值;
结构节点*leftChild;
结构节点*rightChild;
}节点;
类型定义结构树{
内结节;
结构节点**节点;
}树木;
树*initTree(){
/*在C代码(不是C++)中,不必强制转换malloc的返回指针,它是从void*隐式转换而来的*/
tree*atree=malloc(sizeof(tree));/*变量的不同名称*/
节点*阳极=malloc(sizeof(节点));
atree->节点[0]=阳极;
返回atree;
}
int main(){
返回0;
}

不要使用
typedef
'ed名称作为变量名,并且不需要强制转换
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->nodes[0] = malloc(sizeof(node));
    return malloc(sizeof(tree));
}

int main() {
    return 0;
}
#包括
#包括
类型定义结构节点{
int值;
结构节点*leftChild;
结构节点*rightChild;
}节点;
类型定义结构树{
内结节;
结构节点**节点;
}树木;
树*initTree(){
树->节点[0]=malloc(sizeof(node));
返回malloc(sizeof(tree));
}
int main(){
返回0;
}

更改initTree的主体,如下所示:

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

我认为梅尔达德的解释是中肯的

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


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

< P>除了原来的问题,这个代码,即使在它的正确形式也不能工作,仅仅是因为“代码>树::节点< /CUT>(对不起C++符号)。作为指向树的指针,指针不会直接指向树后可用的任何内容。因此,
tree->nodes[0]
在普通指针的情况下本质上与
*(tree->nodes)
相同,不能取消引用。对于树来说,这是一个非常奇怪的头,但是您至少应该分配一个
节点*
来初始化指向指针的指针:

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

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

tree *tree = malloc( sizeof *tree ); tree*tree=malloc(sizeof*tree); 通常认为使用“sizeof variable”是更好的样式 而不是“sizeof(type)”,在本例中是 约定解决了语法错误。我个人认为 这个例子很好地说明了为什么类型转换是 通常这是个坏主意,因为如果 书面:

结构树*tree=malloc(sizeof*tree);
不需要(
typedef struct tree{}tree
)。我现在试过了,它似乎可以编译。但是,它在没有
struct
的情况下工作(但只有当变量的名称与类型名称不冲突时才工作)。@delnan:正是我的观点。。。因此,如果他不更改代码的其余部分,为什么他需要说
struct
。如果他不更改代码的其余部分,那么是的。但是大多数人(看看投票结果)似乎认为重命名变量才是真正的解决方案(它还允许在typename之前删除可能不必要的
struct
)。但是如果有更好的解决方案,为什么不提出更好的解决方案(或者提到劣质的解决方案)?错误的原因(名称冲突)不是因为C。在许多语言中都会出现错误。(但是是的,错误消息是不可理解的。)那么我是否应该永远不要尝试强制转换malloc返回的void?@sombe-您不必(在C中),从
void*
到指针类型的转换是隐式的。@sombe,是的。如果这样做,如果未包括
malloc
的原型,则可能会隐藏一些对
int
的隐式强制转换。 tree *tree = malloc( sizeof *tree ); struct tree *tree = malloc( sizeof *tree );