Структура в массиве обычно лучше; Вы должны использовать это, если у вас нет причин использовать другую форму.
С точки зрения корректности кода, вы должны обрабатывать malloc () сбои. Если у вас в цикле 1000 malloc (), вы с большей вероятностью допустите программную ошибку в своем коде обработки ошибок. Точно так же, если ваша структура данных более сложна, вы, скорее всего, что-то потеряете. Так что одиночный malloc () проще.
С точки зрения скорости выделения, malloc (), очевидно, требует времени для запуска, поэтому один malloc () обычно будет быстрее.
С точки зрения размера памяти, malloc () обычно имеет некоторые накладные расходы при каждом выделении. И, очевидно, указатели являются дополнительной платой. Таким образом, если вы выделите 1000 16-байтовых структур, вы можете получить 16 байт на структуру в служебных данных malloc и 8-байтовый указатель, всего 40 016 байт. Одно выделение займет всего 8 016 байт.
С точки зрения скорости доступа, один массив может быть быстрее, особенно если структуры маленькие или вы читаете структуры по порядку. Если структуры небольшие, то несколько из них поместятся в одну строку кэша, поэтому их можно читать / записывать как группу. Если вы читаете структуры по порядку, процессор, скорее всего, заметит линейный доступ к большому массиву и предварительно загрузит его в кеш. Если вы используете массив указателей и отдельные выделения, то расположение памяти будет более случайным, и ни одна из этих оптимизаций не будет работать. Кроме того, поскольку вы получаете доступ к большему количеству данных (указателям), ваш алгоритм быстрее выпадет из кэша данных.
С точки зрения фрагментации памяти, это зависит. Если у вас достаточно большие структуры (значительная часть общего объема ОЗУ), то вы можете оказаться в ситуации, когда не хватает непрерывной свободной памяти для выделения одного большого массива, но достаточно для выделения массива указателей и отдельные структуры. (Например, если у вас есть 32-разрядная программа в операционной системе, которая ограничивает вас до 2 ГБ памяти, и ваш распределитель памяти выделил что-то еще на полпути через память, то вы не можете сделать одно выделение 1,5 ГБ, но вы могли бы сделать 15 100MB выделений). Такой сценарий встречается редко, потому что люди обычно не работают с такими большими данными.