- Как я буду динамически выделять массив из
struct Register
с каждым регистром, имеющим динамически выделенный массивstruct Field
? - Как я могу получить доступ к каждому из этих участников (могу ли я использовать
Register_A.FieldArray[23].High
?)? Как я могу эффективно инициализировать структуру регистров (при условии, что массив структур регистров является большим)? (Как и сегмент данных, не тратя Compute)Динамически выделять структуру и массив в нем в C
struct Field { char High; char Low; char Attribute; }; struct Register { unsigned int ResetValue; struct Field FieldArray[]; };
ответ
Я решительно отговариваю вас от использования гибкого массива, потому что это не что иное, как клочья. Вы должны вместо этого объявить и использовать его как struct Field *
, malloc
с его размером, как и любой другой динамический массив.
Тем не менее, к malloc
с размером массива n_elem
:
struct Register register = malloc(sizeof(*register) + n_elem * sizeof(*register->FieldArray));
Чтобы получить доступ к элементам:
char high = register->FieldArray[0].High;
Для инициализации: in gcc, at least, можно инициализировать часть массива статически, как любой другой статический массив. Я не уверен, как справляются с другими компиляторами.
Почему гибкие массивы не рекомендуется:
Я свяжусь this post, но я не думаю, что ответ является полным (большинство из уныния, потому что это с-99 только), так что я Я добавлю свои мысли.
Это исключение. По сути, вы объявляете массив равным нулю и каждый раз получая доступ к нему за пределы, только в той степени, в какой вы выделили. Вы не можете использовать структуру с гибким массивом точно так же, как любая другая структура, например. вы не можете принять гибкий массив sizeof
. Если вы объявляете статический или массив из них, вы не можете использовать элемент массива, потому что для него нет места.
Пример использования их в массиве:
#include <stdio.h>
struct test {
int val;
int arr[];
};
int main() {
struct test tarr[2];
printf("%p\n%p\n", &tarr[0].arr[0], &tarr[1].val);
}
Выход:
0x7fff59b67164
0x7fff59b67164
Они по тому же адресу. Если вы попытаетесь написать члену массива, вы перепишете следующий объект. Если вы попытаетесь прочитать его, вы будете читать данные со следующего объекта. В зависимости от дополнения, это может быть даже бессмысленным значением из прокладки.
Это как заявления goto
, оба потенциально полезны, но чаще всего плохая идея. Если вы не знаете, почему они опасны, вы не должны их использовать (в реальном коде, это неплохая идея, чтобы поиграть с ними в тестовой программе, чтобы увидеть, как правильно их использовать и как они могут внедрять проблемы).
Вы собираетесь должны знать, насколько большой FieldArray есть. Если он не исправлен, вам нужно объявить с максимальным значением. Тогда вы можете просто Alloc Реестр и доступ, как было указано
способ сделать это путем изменения размера struct Register
:
struct Register
{
unsigned int ResetValue;
struct Field FieldArray[1];
};
struct Register *Register_Create()
{
struct Register *reg = calloc(1, sizeof(struct Register) - sizeof(struct Field));
// check for NULL pointer
return reg;
}
struct Register *Register_SetSize(struct Register *reg, size_t size)
{
// check for NULL
reg = realloc(reg, sizeof(struct Register) + sizeof(struct Field) * (size - 1));
// check for NULL
return reg;
}
Вот пример того, как использовать этот :
struct Register *reg = Register_Create();
reg = Register_SetSize(register, 5);
// You now have space for 5 elements in reg->FieldArray
reg->FieldArray[3].High = 'B';
Имейте в виду, что это решение работает только если FieldArray
помещается в конце struct
.
Элементы гибкого массива являются частью C99.
- можно выделить
struc
с гибким элементом массива так же, как вы думаете, вы должны:malloc(sizeof(struct Register) + sizeof(struct Field[n]))
, гдеn
размера вы хотите. Не забудьте инициализировать массив и следить заn
, лучше посвящая члена к этой цели - да
КСТАТИ: malloc
выше, может тратить несколько байт из-за дополнения, но обычно это не стоит думать о точной формуле. Минимальный размер макс и использует offsetof
.
- 1. Динамически выделять массив неопределенного размера в C
- 2. Как динамически выделять массив строк в C?
- 3. Как динамически выделять массив указателей в C++?
- 4. Как динамически выделять 2D-массив в C++?
- 5. Динамически выделять массив в struct - c
- 6. Как динамически выделять структуру, которая содержит указатель?
- 7. Как динамически выделять двумерный массив указателей? (C)
- 8. Как динамически выделять структуру, содержащую несколько массивов?
- 9. Динамически выделять массив структур с помощью C++
- 10. Динамически выделять массив указателей файлов
- 11. Динамически выделять массив размером 0
- 12. Как динамически выделять/вырастить массив строк в C++?
- 13. динамически выделять массив связанных списков
- 14. Динамически выделять массив структур проблемы
- 15. Как динамически выделять 2d-массив и почему?
- 16. Динамически выделять массив std :: string
- 17. Как динамически выделять массив структур?
- 18. Динамически выделять память для массива в C
- 19. Динамически выделять строковую матрицу в C
- 20. Как динамически выделять массив 2d для структуры
- 21. Как динамически выделять массив целых чисел в C
- 22. использовать новый оператор динамически выделять массив в C++
- 23. Как динамически выделять массив указателей на объекты в Objective-C?
- 24. Как динамически выделять массив векторов с помощью «new» в C++?
- 25. Как динамически выделять массив указателей на объекты?
- 26. Динамически создать и инициализировать массив указателей на структуру в C
- 27. Как динамически выделять массивы в C++
- 28. Как динамически выделять матрицу в C?
- 29. Как динамически выделяет структуру в C?
- 30. Динамически выделять SIMD Vector как массив удвоений
+1 для предотвращения использования гибкого массива (не говоря уже об ошибке) – pmg
Почему использование гибкой решетки обескуражено? Я думал, что под капотом это так же, как с помощью указателей. Может ли он использоваться в этом случае? – Jean
@alertjean: прочитайте раздел 6.7.2.1 в [Стандарт C99] (http://www.open-std.org/JTC1/sc22/wg14/www/docs/n1256.pdf) и сделайте собственные выводы. – pmg