 user2719875 -3 years ago 129
C Question

# multiple node values all point to the same value even when using malloc and strcpy

Edit: just trying to learn C and coming from a Python background, hopefully I don't get downvoted too much for this.

I have this struct:

``````struct TreeNode {
char *value;
struct TreeNode *sibling;
struct TreeNode *child;
};
``````

I have this code to create nodes:

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

and this is the code in another function which creates the node (where values is an array of strings):

``````struct TreeNode a = create_node(values);
struct TreeNode b = create_node(values);
struct TreeNode c = create_node(values);
struct TreeNode d = create_node(values);
printf("%s\n", a->value);
printf("%s\n", b->value);
printf("%s\n", c->value);
printf("%s\n", d->value);
``````

When I compile and run this, it prints
`values`
four times (meaning the value for node a, b, c and d are all
`values`
).

Question 1) Why do they all have the same value?

Note: Code which works properly is:

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

Question 2) Why does the latter work, and the former doesn't?

Question 3) In the latter, shouldn't it be
`node->value = malloc(sizeof(char) * (strlen(value) + 1));`
rather than just
`node->value = malloc(strlen(value) + 1);`
? Filip Kočica

2) Why does the latter work, and the former doesn't?

Becouse you are returning address of local variable. In the time you are dereferencing pointer is the local variable out of scope (ended it's lifetime) which leads to undefined behavior. In function you have to return pointer only to variable(declared in function) with dynamic storage duration.

3) In the latter, shouldn't it be node->value = malloc(sizeof(char) * (strlen(value) + 1)); rather than just node->value = malloc(strlen(value) + 1);

Size of `char` is `1B` by standard.

C99, section 6.5.3.4

When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1.

1) Why do they all have the same value?

Becouse `UB`, change `create_node` to:

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

and it won't :-)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download