I'm trying to implement a node structure in C that can have arbitrary many child nodes. I wanted to do this idea by using a pointer to a pointer to a struct instead of using an array:
struct Node {
char name[10]; // Name of the node.
int data; // The data it holds.
struct Node *parent; // The parent node.
struct Node **child; //
};
(I don't know if this is the best or even a good but I'm just playing around to learn C better).
I also implemented a print
function that prints the members:
void print(struct Node node);
(I know this only prints one node so it wouldn't work for a node with multiple child-nodes).
However, when I try to use this in a main
function I get a segmentation fault (core dump)
:
#include <stdio.h>
#include <stdlib.h>
struct Node {
char name[10]; // Name of the node.
int data; // The data it holds.
struct Node *parent; // The parent node.
struct Node **child; //
};
void print(struct Node node) {
printf("Name: %s\n", node.name);
printf("Data: %d\n", node.data);
printf("Parent: %s\n", (*node.parent).name);
printf("Children: %s\n", (**node.child).name);
}
int main() {
struct Node n1 = { "Parent", 1, NULL, NULL };
struct Node n2 = { "Child1", 2, &n1, NULL };
*n1.child = &n2;
print(n1);
print(n2);
return 0;
}
Can anybody see what I'm doing wrong here and what I should do instead?
Kind regards,
Edit:
Actually what I wanted to achieve was to create the child member like this (I'm using an example with an array of integers to illustrate what I mean):
int *p = malloc(sizeof(int));
*p =1;
*(p+1)=2;
but instead of p pointing to integers having it point to pointers to struct Node. Is this doable?
You get a segmentation fault because you do not test if the parent
node is valid, nor if the child
node is a valid pointer, nor that the pointer it points to is valid too. The initialization of n1.child[0]
is incorrect too.
*n1.child = &n2;
has undefined behavior because n1.child
is a null pointer.printf("Parent: %s\n", (*node.parent).name);
has undefined behavior for n1
;printf("Children: %s\n", (**node.child).name);
has undefined behavior for n2
.Alos note that it is idiomatic in C to pass structure pointers rather than copies of structures to functions such as print
.
Here is a modified version, assuming child
, if not NULL
points to a NULL
terminated array of node
pointers.
EDIT: I added an add_child
function to illustrate how to construct trees from individual nodes.
#include <stdio.h>
#include <stdlib.h>
struct Node {
char name[10]; // Name of the node.
int data; // The data it holds.
struct Node *parent; // The parent node.
struct Node **child; // if not NULL, points to a NULL terminated array of pointers.
};
void print(const struct Node *node) {
if (node) {
printf("Name: %s\n", node->name);
printf("Data: %d\n", node->data);
if (node->parent) {
printf("Parent: %s\n", node->parent->name);
}
if (node->child) {
printf("Children:");
for (int i = 0; node->child[i]; i++) {
printf("%s %s", i > 0 ? "," : "", node->child[i]->name);
}
printf("\n");
}
}
}
// add a child node to a parent's child list.
// return 0 upon success or an error code on failure
int add_child(struct Node *parent, struct Node *chid) {
if (parent == NULL)
return 1;
if (child == NULL)
return 2;
size_t nchild = 0;
if (parent->child != NULL) {
while (parent->child[nchild] != NULL)
nchild++;
}
struct Node *new_child = realloc(parent->child, (nchild + 2) * sizeof(*new_child));
if (new_child == NULL)
return 3;
parent->child = new_child;
parent->child[nchild++] = child;
parent->child[nchild] = NULL;
child->parent = parent;
return 0;
}
int main() {
struct Node n1 = { "Parent", 1, NULL, NULL };
struct Node n2 = { "Child1", 2, NULL, NULL };
struct Node n3 = { "Child2", 3, NULL, NULL };
add_child(&n1, &n2);
add_child(&n1, &n3);
print(&n1);
print(&n2);
print(&n3);
return 0;
}