cdata-structurestreemallocrealloc

segfault trying to find bottom nodes of tree and adding to dynamic array in C


when calling init_model() function I am trying to recursively travel through a tree and append the pointers to the lowest treenodes in an array of treenode pointers. however I am getting segfault when I traverse the list trying to print it.

void rec_find_inputs(TreeNode* root, TreeNode** arr, int* len_arr) {
    if (!(root->num_children)) {
        arr = realloc(*arr, *len_arr * sizeof(TreeNode*));
        arr[*len_arr] = root;
        (*len_arr)++;
    } else {
        for (int i = 0; i < root->num_children; i++) {
            rec_find_inputs(root->children[i], arr, len_arr);
        }
    }
}


void init_model(TreeNode* neuron_config) {
    int rec_params_len = 0;
    TreeNode** rec_params_arr = (TreeNode**) malloc(sizeof(TreeNode*) * 1);

    rec_find_inputs(neuron_config, rec_params_arr, &rec_params_len);

    printf("--------------\n");
    printf("%d\n", rec_params_len);
    for (int i = 0; i < rec_params_len; i++) {
        printf("%f\n", rec_params_arr[i]->data);
    }
}

I am not sure if it is a problem with how I am allocating the memory or if I am iterating through the array incorrectly.


Solution

  • This code snippet

    arr = realloc(*arr, *len_arr * sizeof(TreeNode*));
    arr[*len_arr] = root;
    

    is invalid.

    There are allocated *len_arr elements of an array. So the valid range of indices is [0, *len_arr). However there is used the invalid index *len_arr outside the range

    arr[*len_arr] = root;
    

    Another problem is that you need to pass the pointer arr by reference through a pointer to it. That is the function declaration should look at least like

    void rec_find_inputs(TreeNode* root, TreeNode*** arr, int* len_arr) {
                                         ^^^^^^^^^^^ 
    

    Otherwise the original pointer passed to the function as an argument will stay unchanged.