malloc с многомерным массивом - PullRequest
3 голосов
/ 22 ноября 2011

Я работаю над словарем, структура которого:

typedef union _dict {
    union _dict * children[M];
    list * words[M];
} dict;

Инициализация:

dict *d = (dict*) malloc(sizeof(dict));

Я пытаюсь сделать следующее:

dict *temp;
temp = d;

temp=temp->children[0];
temp=temp->children[0];

first temp->children[0] работает, но не второй. Я пытаюсь понять почему. Я думаю, что это проблема выделения памяти.

Редактировать 1: Я пробовал следующий код:

dict *d = (dict*) malloc(sizeof(dict));

dict *temp;
temp = d;

dict *d2 = (dict*) malloc(sizeof(dict));
temp->children[0] = d2;

temp = temp->children[0];
temp = temp->children[0];
temp = temp->children[0];

Теперь это работает, но я не понимаю, почему ... Я имею в виду, я не позволил памяти для следующих детей.

Редактировать 2: Итак, теперь я хотел бы использовать это в моем алгоритме. Блок кода, в котором я застрял, следующий:

list *l;
if (temp->words[occur] != NULL) {
    /* ... */
}
else {
    l = list_new();
    temp->words[occur] = (list*) malloc(sizeof(list));
    temp->words[occur] = l;
}
list_append(l,w);
list_print(l);

Если я поставлю temp->words[occur] = NULL; перед этим блоком, слово будет успешно добавлено, но каждый раз при использовании алгоритма создается новый список. Я хотел бы добавить свое слово в ранее созданный список, предполагая, что оно существует.

Инструкция bzero((void*)d, sizeof(dict)); используется после инициализации dict.

Ответы [ 5 ]

2 голосов
/ 22 ноября 2011

children никогда не инициализируется, поэтому он содержит любой мусор, который был в памяти раньше. После первого temp = temp->children[0], temp - указатель на неизвестную территорию.

2 голосов
/ 22 ноября 2011

Сначала в temp у вас есть действительный указатель на объект (выделенный с помощью malloc).Затем вы присваиваете неинициализированный указатель на temp и пытаетесь разыменовать его с ожидаемыми последствиями.

1 голос
/ 22 ноября 2011

Проблема заключается в том, что первый children создается как указатель на dict, например: union _dict * children[M];, но каждый элемент в этом массиве не выделяется автоматически.Таким образом, ваш второй вызов использует «дочерний элемент», для которого не было создано dict пространства.

Если вы хотите, чтобы он работал правильно, что-то вроде этого должно решить проблему:*

Каждому дочернему элементу должна быть выделена память, или вы просто получаете ошибки мусора и / или сегмента.

0 голосов
/ 22 ноября 2011

Я думаю, что использование второго раза может вызвать ошибку сегментации.

см.

dict *d = (dict*) malloc(sizeof(dict));  // once you have malloc



dict *temp;
temp = d;

temp=temp->children[0];  // that is going to use here

для использования во второй раз, когда у вас нет malloc ..? прямо так, чтобы использовать его таким образом, вы должны malloc как

 d->children[0] = (dict*) malloc(sizeof(dict));
0 голосов
/ 22 ноября 2011
temp=temp->children[0];

Вы никогда не назначаете значение для temp->children[0]. Таким образом, после этой строки кода, temp содержит мусор.

...