0

I'm having difficulty tracking down a problem with pointers returning null in my node structure. I simplified the program to the most basic functions so you could see exactly where the problem is.

This is a basic node tree set up where nodes can be added to each other to create a tree like structure. When creating and adding nodes everything works fine.

I have a print function which prints the node name and the names of it's children as well and here is where the problem is. Whenever I pass a node to the function the pointers to its children always return null. However, I can access the children pointer don't return null when accessed directly from the parent they only return null when the parent is copied into the function.

I'm compiling in C on Linux Mint 19. I included the header, code, and a basic example.

----header----

#ifndef node_h
#define node_h

typedef struct Node node;

struct Node {
    node* parent;
    node** children;
    char* name;
    int count;
};

node* create_node(char* name);

void add_child_node(node* parent, node* child);

void print_node(node* n);

#endif

----c file----

#include <stdio.h>
#include <stdlib.h>
#include "node.h"

node* create_node(char* name) {
    node* n = malloc(sizeof(node));
    if (n == 0) {
        printf("Unable to create node %s.\n", name);
        exit(1);
    }
    n->name = name;
    n->parent = 0;
    n->children = 0;
    //n->map = create_stringmap();
    n->count = 0;
    return n;
}

void add_child_node(node* parent, node* child) {
    child->parent = parent;
    int count = parent->count + 1;
    parent->children = realloc(parent->children, sizeof(node) * count);
    if (parent->children == 0) {
        printf("Unable to add child node %s to parent %s.\n", child->name, parent->name);
        exit(1);
    }
    if (child == 0) {
        printf("The child node you are attempting to add to %s is null.\n", parent->name);
        exit(1);
    }
    // Add child to end of array.
    parent->children[parent->count] = child;
    parent->count = count;
}

void print_node(node* n) {
    //print_node_path(n);
    printf("%s\n", n->name);
    int count = n->count;
    for (int i = 0; i < count; i++) {
        printf("%p\n", n->children[count]);
        printf("%s\n", n->children[count]->name); // Crashes because children are null.
        //print_node(n->children[count]); 
    }
}

----test file----

#include <stdio.h>
//#include <unistd.h>
#include <stdlib.h>
#include "node.h"

// gcc -Wall node.c stringstest.c -o stringstest && ./stringstest

int main() {

//while (1) {

// Create tree
node* root = create_node("root");
node* branch1 = create_node("branch1");
node* branch2 = create_node("branch2");

// Add children
add_child_node(root, branch1);
add_child_node(root, branch2);

printf("%s\n" , root->children[0]->name);
printf("%s\n" , root->children[1]->name);
printf("%p\n", root->children[0]);
printf("%p\n", root->children[1]);
print_node(root); // Crashes because children are return null.
// This works since no children are accessed in the loop.
//print_node(branch2);

//usleep(100);
//}

return 0;

}

In the example the nodes children work fine when accessed directly the problem is in the print_node function. When the node is passed to it the children now become null aka 0.

This is the exact method I use to store and access arrays of pointers in other libraries. Perhaps I'm missing something simple. Either way it always helps to get an outside fresh perspective.

1 Answer 1

1

Inside the printing loop this

    printf("%p\n", n->children[count]);

ought to be

    printf("%p\n", n->children[i]);

(Perhaps have a break? ;>)


Unrelated, but strictly speaking using the p conversion specifier with something else than a void-pointer is invoking undefined behaviour.

So better do:

    printf("%p\n", (void*) n->children[i]);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I literally laughed at myself for missing something so obvious. I had been debugging this for hours and that slipped by me everytime. I think its time to take a break before I get back to work :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.