C结构和malloc问题(C)
令人惊讶的是,即使是最小的程序也能在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
#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 );