即使使用malloc和strcpy,多个节点值都指向相同的值

时间:2017-08-15 21:28:56

标签: c pointers nodes

编辑:只是尝试学习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);吗?

2 个答案:

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

它赢了: - )