Struct Hack с Array of Struct Type

EDIT – ранее опубликованный код обсуждался, потому что он не компилировался

Скажем, у меня есть следующий вариант взлома структуры:

typedef struct hack *Hack;
struct hack {
    char* value;
    Hack arr[1];
};

Что именно я должен использовать? Должен ли я делать что-то вроде:

malloc(sizeof(struct hack) + sizeof(struct hack)*(numElems-1));

который можно было бы сократить до:

malloc(sizeof(struct hack) * numElems);

Это правильно?


person Kvass    schedule 03.04.2013    source источник
comment
Не работает, struct не может содержать член того же типа или его массив.   -  person Daniel Fischer    schedule 04.04.2013
comment
Ваша структура не будет компилироваться   -  person Tony The Lion    schedule 04.04.2013
comment
Я протестировал его с помощью typedef struct hack *Hack, но не только с typedef struct hack Hack, который, как правильно указали некоторые из вас, не будет компилироваться. Однако мой вопрос по-прежнему означает * Hack.   -  person Kvass    schedule 04.04.2013
comment
Помогает ли это вам: ?   -  person n0741337    schedule 04.04.2013
comment
Я уже знал, как это сделать, но все равно спасибо за ссылку. Я все еще немного смущен в этом конкретном примере.   -  person Kvass    schedule 04.04.2013


Ответы (1)


Я не думаю, что ваш первый код правильный. Это "неполный тип элемента"

typedef struct hack Hack;
struct hack {
    char* value;
    Hack arr[1];
};

равно:

struct hack {
    char* value;
    struct hack arr[1];  /* Here wrong */
};

В неправильном месте вы пытаетесь определить массив struct hack, но: определение struct hack еще не завершено. Ооооооооооооооооооооооооооо ты измени его.

Для вашего нового кода это должно быть:

typedef struct hack *Hack;
struct hack {
    char* value;
    Hack arr;
};
Hack node = malloc(sizeof(struct hack));
node->arr = malloc(sizeof(struct hack) * numElems);

В этом случае «узел» является указателем на взлом одной структуры. А член "arr" этой сущности - еще одна точка массива структуры взлома. В противном случае вы могли бы построить свои данные как типичный связанный список.

Обновление: обратите внимание, все значения в узле и (node->arr)[i] не инициализированы! Вы должны memset() обнулить их все сразу после malloc(). Или обязательно присвойте допустимое значение перед любым использованием. Если вы используете его до присвоения действительного значения, лучше всего столкнуться с ошибкой сегментации. В худшем случае это будет стоить вам нескольких дней, чтобы выяснить, где что-то не так.

person Sheng    schedule 03.04.2013
comment
Все это имеет смысл — после этого я могу безопасно получить и установить (node->arr)[i] для 0‹=i‹numElems? - person Kvass; 04.04.2013
comment
Под этим я подразумеваю установить, а затем получить после установки; получение первого без установки должно segfault не так ли? - person Kvass; 04.04.2013
comment
Да, вы можете использовать (node-›arr)[i] для 0‹=i‹numElems'. Но обратите ВНИМАНИЕ, все значения в узле и (node-›arr)[i] не инициализируются! Вы должны memset() обнулить их все сразу после malloc(). Или обязательно присвойте допустимое значение перед любым использованием. Если вы используете его до присвоения действительного значения, лучше всего столкнуться с ошибкой сегмента. В худшем случае это будет стоить вам нескольких дней, чтобы выяснить, где что-то не так. - person Sheng; 04.04.2013