编辑:只是尝试学习C并来自Python背景,希望我不会因此而过多地投票。
我有这个结构:
struct TreeNode {
char *value;
struct TreeNode *sibling;
struct TreeNode *child;
};
我有这个代码来创建节点:
struct TreeNode* create_node(const char* value) {
struct TreeNode node;
node.value = malloc(sizeof(char) * (strlen(value) + 1));
strcpy(node.value, value);
node.sibling = NULL;
node.child = NULL;
struct TreeNode* node_ptr = &node;
return node_ptr;
}
这是另一个创建节点的函数中的代码(其中values是一个字符串数组):
struct TreeNode a = create_node(values[0]);
struct TreeNode b = create_node(values[1]);
struct TreeNode c = create_node(values[2]);
struct TreeNode d = create_node(values[3]);
printf("%s\n", a->value);
printf("%s\n", b->value);
printf("%s\n", c->value);
printf("%s\n", d->value);
当我编译并运行它时,它会打印values[3]
四次(意味着节点a,b,c和d的值都是values[3]
)。
问题1)为什么它们都具有相同的值?
注意:正常运行的代码是:
struct TreeNode* create_node(const char* value) {
struct TreeNode* node = malloc(sizeof(struct TreeNode));
node->value = malloc(strlen(value) + 1);
strcpy(node->value, value);
node->child = NULL;
node->sibling = NULL;
return node;
}
问题2)为什么后者有效,而前者无效?
问题3)在后者中,它不应该是node->value = malloc(sizeof(char) * (strlen(value) + 1));
而不仅仅是node->value = malloc(strlen(value) + 1);
吗?
答案 0 :(得分:2)
struct TreeNode* create_node(const char* value) {
struct TreeNode node;
node.value = malloc(sizeof(char) * (strlen(value) + 1));
strcpy(node.value, value);
node.sibling = NULL;
node.child = NULL;
struct TreeNode* node_ptr = &node;
return node_ptr;
}
struct node
是此函数的本地,因此当函数返回时它不再存在。但是你返回一个指向它的指针。对于不再存在的对象的指针,调用者应该做什么?
答案 1 :(得分:1)
2)为什么后者有效,而前者没有?
因为你正在返回局部变量的地址。在您解除引用指针的时间内,局部变量超出范围(结束它的生命周期),这导致undefined behavior。在函数中,您必须仅使用动态存储持续时间将指针返回到变量(在函数中声明)。
3)在后者中,不应该是node-> value = malloc(sizeof(char)* (strlen(value)+ 1));而不仅仅是node-> value = malloc(strlen(value)+ 1);
标准char
的大小为1B
。
C99,第6.5.3.4节
当应用于具有char,unsigned char或者类型的操作数时 signed char,(或其合格版本),结果为1。
1)为什么它们都具有相同的值?
Becouse UB
,将create_node
更改为:
struct TreeNode* create_node(const char* value)
{
struct TreeNode * node = (struct TreeNode*)malloc (sizeof(struct TreeNode));
node->value = malloc(sizeof(char) * (strlen(value) + 1));
strcpy(node->value, value);
node->sibling = NULL;
node->child = NULL;
return node;
}
它赢了: - )