Массив указателей на структуры в указателе на структуру - PullRequest
0 голосов
/ 18 мая 2018

Приведенный ниже код пытается инициализировать узел и при этом динамически инициализировать массив указателей на дочерние узлы.Тем не менее, я получаю Segmentation fault: 11, когда пытаюсь получить доступ к детям.Я понимаю, что не должен получать каких-либо значимых значений (то есть это будет просто мусор в памяти), но я не знаю, почему я получаю ошибку сегментации.

#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>

#define INIT_SIZE 10

typedef struct node_t node_t;

struct node_t {
  char *word;
  node_t **children;
  int arr_len;
};

void set_array_vals(node_t *root);

int main(int argc, char const *argv[]) {
    char *word = "hello";

    node_t *root = malloc(sizeof(node_t));
    assert(root);

    root->children = malloc(sizeof(node_t *) * INIT_SIZE);
    assert(root->children);
    root->arr_len = INIT_SIZE;

    root->word = malloc((sizeof(char)) * (strlen(word) + 1));
    assert(root->word);
    strcpy(root->word, word);

    set_array_vals(root);
    printf("Arr len: %d\n", root->arr_len);

    return 0;
}

void set_array_vals(node_t *root) {
    int i;
    for (i=1; i<root->arr_len; i++) {
        node_t *this_node = root->children[i];
        printf("%d: %d\n", i, this_node->arr_len);
    }
}

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Как указали другие, во-первых, children имеет тип node_t **, и вы выделили память только для root->children, а не для root->children[row].Выделите память динамически для root->children[row] и назначьте некоторые значения.Это может выглядеть так:

 root->arr_len = INIT_SIZE;
 for(int row = 0; row < root->arr_len ;row++) {
         root->children[row] = malloc(sizeof(node_t));/* allocate memory for each children */
         root->children[row]->arr_len = row + 99;/* ?? assign some values into member of struct so that you can print in
                                                                            set_array_vals & verify  */
            }

И в set_array_vals() начинайте печать с i=0, как указано выше, вы выделяете память от root->children[0] до root->children[9], а доступ за пределы размера может привести к неопределенному поведению.

void set_array_vals(node_t *root) {
        for (int i = 0; i < root->arr_len; i++) { /* start printing from i=0 , not i=1 */
                #if 0
                node_t *this_node = root->children[i]; /* no need of any temporary pointer */
                printf("%d: %d\n", i, this_node->arr_len);
                #endif
                printf("%d: %d\n", i, root->children[i]->arr_len);
        }
}
0 голосов
/ 18 мая 2018

В set_array_vals вы получаете указатели из «массива» root->children, но этот массив не инициализируется, и указатели будут неопределенными и кажущимися случайными.Разыменование этих указателей приводит к неопределенному поведению .

Кроме того, вы, похоже, забыли, что индексы массива начинаются с ноль .И как только вы сделаете все указатели в массиве root->children действительными, вы должны будете не забывать инициализировать структуры, на которые они также указывают, иначе значение this_node->arr_len будет неопределенным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...