#c #arrays #struct
#c #массивы #структура
Вопрос:
Цель
Динамически создайте массив из массива структур элементов (определено ниже)
typedef struct {
void* data;
} Element;
Вопрос
Я знаю, как malloc массив структур элементов
Element* arrayOfElements = malloc(4 * sizeof(Element));
Но тогда как мне Malloc массив из вышеперечисленного? (массив arrayOfElements)
Вопрос 2
Допустим, массив arrayOfElements называется arrayOfArrayStruc, как бы мне приступить к установке значений внутри него
Например, я хочу скопировать 65 в arrayOfElements [2], который находится внутри arrayofarraystruct1, как бы я к этому отнесся?
Я знаю, как это сделать, если бы я хотел скопировать 65 прямо в arrayOfElements[2]
arrayOfElements[2].data = malloc( sizeof(int) );
ptr = arrayOfElements[2].data;
*ptr = 65;
но я не уверен, как это сделать, если arrayOfElements[2] находится внутри arrayofarraystruct1.
Редактировать
Чтобы сделать более ясной мою цель, я нарисовал картинку
Итак, зеленым цветом выделен элемент структуры, определяемый
typedef struct {
void* data;
} Element;
Затем красным цветом (в котором было 4 зеленых прямоугольника) выделен массив структур элементов, которые я malloc’d использовал
Element* arrayOfElements = malloc(4 * sizeof(Element));
Что я хочу сделать, это сохранить вышеуказанное ^^ в массиве или создать массив указателей (который представляет собой синюю рамку с красными рамками в ней)
Итак, на рисунке «Массив элементов» содержит структуры из 4 элементов, тогда я хочу создать массив для хранения 4 «Массив элементов» (или массив из 4 указателей, указывающих на каждый «Массив элементов»)
Комментарии:
1. Я думаю, ты этого не хочешь. Структура данных, о которой вы думаете, на самом деле не очень хороша, если вы можете использовать
struct
s, вы можете записать свой » массив » в виде структуры и иметь такой массив.2. я не уверен на 100%, что понимаю вас, извините
3. По моему опыту, массив массивов — это почти всегда УЖАСНАЯ вещь. Обычно ученые (я один из них) представляют данные подобным образом, потому что это кажется естественным, но очень часто это не ЕСТЕСТВЕННЫЙ способ сделать это программистом.
4. Ваша диаграмма не представляет код, который у вас есть до сих пор … если предполагается, что красный цвет означает указатель
arrayOfElements
, то он не содержит зеленых элементов. Зеленые элементы находятся в своем собственном блоке, и указатель указывает на него. Массив содержит его элементы, указатель является отдельным элементом массива и указывает на первый элемент массива.5. Да, рисунок примерно такой, каким я его себе представлял, но не как это работает, я немного почитал, и теперь я понимаю, что вы пытались мне сказать, спасибо 🙂 . @Anders K диаграмма — это то, как это работает, и это то, к чему я стремился (ну, должен был стремиться) …. говоря, что это кажется довольно очевидным
Ответ №1:
Если вам нужен массив элементов *, то вы могли бы сделать что-то вроде этого, где n
— количество указателей:
Element** arrayOfStructs = malloc( n* sizeof(Element*) );
Итак, при n = 4; вы получаете массив из 4 указателей:
Массив конструкций
---
| | ->
---
| | ->
---
| | ->
---
| | ->
---
Теперь выделите для каждой записи в arrayOfStructs so if m
количество элементов:
for (int i = 0; i < n; i)
{
arrayOfStructs[i] = malloc(m * sizeof(Element));
}
Поскольку у каждого элемента есть указатель на данные, вам также необходимо выделить то, на что он указывает:
for (int i = 0; i < n; i)
{
arrayOfStructs[i] = malloc(m * sizeof(Element));
for (int j = 0; j < m; j)
{
arrayOfStructs[i][j].data = malloc(sizeof(int));
}
}
После этого в памяти у вас будет следующее:
Допустим, m = 3;
Массив конструкций
--- --- --- ----
| | -> | | | | array of Elements
--- --- --- ---- --- --- ----
| | -------------------> | | | |
--- --- --- ---- --- --- ----
| | -> | | | |
--- --- --- ---- --- --- ----
| | -------------------> | | | |
--- --- --- ----
каждый элемент в «массиве элементов» 1 ..3 (или, скорее, 0 .. 2) указывает на разные «данные» (ниже в массиве элементов повернут на 90 градусов, чтобы мне было легче рисовать прямоугольники):
--- ---
| | -> | | integer
--- --- ---
| | ---------> | |
--- --- ---
| | -------------------> | |
--- ---
Комментарии:
1. Итак, как бы я создал, скажем, 2-й элемент arrayOfElements, на который указывает 3-й элемент arrayOfStrucs Я могу сделать это только с помощью arrayOfElements, но я не уверен, как это сделать, когда на него указывает arrayOfStrucs
Ответ №2:
arrayOfElements
это имя переменной-указателя. У вас не может быть массива имен.
У вас мог бы быть массив переменных-указателей. Вы можете написать код для этого, он такой же, как код для массива int, но вместо int используйте тип указателя. Затем вам нужно было бы инициализировать каждую из этих переменных-указателей в массиве таким же образом, как вы делаете сейчас.
Однако, как указано в публикации, вопрос задавался для «массива массивов», а не «массива указателей». «Массив массивов» — это массив, тип элемента которого является массивом (не указателем).
Вот нединамически распределяемый массив: int x[4][5];
. Это массив из 4 элементов, причем каждый элемент представляет собой массив из 5 целых чисел.
Для динамического выделения одной из них используется тот же код, что и для динамического выделения любого массива из 4 элементов. Мы просто используем int[5]
в качестве типа элемента, вместо int
или чего-то еще.
Тип указателя на первый элемент: «указатель на int[5]
«. В синтаксисе C это записывается int (*)[5]
— не int *[5]
, который является массивом указателей.
Одним из способов написания кода было бы:
int (*px)[5] = malloc(4 * sizeof(int[5]));
надеюсь, вы можете увидеть сходство между этим и malloc
в вашем вопросе. Мы только что заменили Element
на int[5]
. (Итак, теперь ваша задача — использовать Element[5]
вместо int[5]
. Или любого другого размера вместо 5
).
Чтобы избежать повторения (и, следовательно, избежать возможности ошибок), можно использовать общую идиому:
int (*px)[5] = malloc(4 * sizeof *px);
это 4 элемента, каждый из которых имеет правильный размер для того, на что указывает указатель.
Комментарии:
1. Итак, допустим, я хочу, чтобы ARRAYOFSTRUCTS содержал 5 элементов (элементами являются arrayOfElements, которые, в свою очередь, имеют 4 элемента), так что я бы сделал: Элемент * arrayOfStrucs [5] = malloc(5 * sizeof(arrayOfElements [4]));
2. @CrispyCashew Нет, попробуйте еще раз 🙂 (Посмотрите на последнюю строку кода в моем ответе и измените
int
наElement
, а также поменяйте местами все4
и5
).3. Элемент (*px)[5] = malloc(5 * sizeof(элемент[4]));
4. я говорил 5 * sizeof(arrayOfElements[4])); правильно? поскольку я хочу выделить достаточно памяти, чтобы вместить 5 arrayOfElements[4] (которые затем содержат структуры из 4 элементов).
5. Это 5 строк по 4 элемента. Я думал, вы сказали, что хотите 4 строки по 5 элементов в вашем первом комментарии. Но в любом случае вы должны сопоставить размер слева с размером в
sizeof
.