структуры, содержащие структуры против структур, содержащих указатели - PullRequest
3 голосов
/ 28 февраля 2011

Следующий вопрос относится к программированию на Си.Я использую компилятор Microchip C30 (потому что знаю, что кто-то спросит)

В чем разница между структурой, содержащей несколько других структур, и структурой, содержащей несколько указателей на другие структуры?Один делает для более быстрого выполнения кода, чем другой?Одна техника использует больше или меньше памяти?Распределяется ли память одновременно в обоих случаях?

Если я использую следующий код, автоматически ли выделяется память для подсистемы?

// Header file...

typedef struct{
    int a;
    subStruct * b;
} mainStruct;

typedef struct{
    int c;
    int d;
}subStruct;

extern mainStruct myMainStruct;

// source file...
mainStruct myMainStruct;

int main(void)
{
   //...
{

Ответы [ 5 ]

2 голосов
/ 28 февраля 2011

Если вы используете указатель, вы должны выделить память самостоятельно.Если вы используете подструктуру, вы можете выделить всю вещь за один раз, используя malloc или в стеке.

Что вам нужно, зависит от вашего варианта использования:

  • Указатели дадут вам меньшие struct
  • Подструктуры обеспечивают лучшую локальность ссылок
  • Указатель может указывать либо на один struct, либо на первый член в их массиве, тогда какподструктуры являются самодокументируемыми: всегда есть одна из них, если вы не используете массив явно
  • Указатели занимают некоторое пространство, для самого указателя + накладные расходы из дополнительных выделений памяти

И нет, не имеет значения, какой компилятор вы используете:)

2 голосов
/ 28 февраля 2011

Память для указателей не выделяется автоматически, но когда в вашей структуре содержится целая структура, это происходит.

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

Но с помощью poniters вы можете совместно использовать одни и те же подструктуры во многих структурах (но это усложняет их изменение и удаление в дальнейшем).

0 голосов
/ 28 февраля 2011

В чем разница между структурой, которая содержит несколько других структур, и структурой, которая содержит несколько указателей на другие структуры?

В первом случае у вас есть по существу один большойструктура в смежной памяти.В случае «указателей на структуры» ваша основная структура содержит только адреса для подструктур, которые выделяются отдельно.

Способствует ли одно выполнение кода быстрее, чем другому?

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

Использует ли один метод больше или меньше памяти?

В методе указателя используется number_of_pointers * sizeof(void*) большеобъем памяти.sizeof(void*) будет 4 для 32-битной и 8 для 64-битной.

Распределяется ли память в обоих случаях одновременно?

Нет,вам нужно пройти через каждый указатель в вашей основной структуре и выделить память для подструктур с помощью malloc ().

Заключение

Указатели добавляют слой косвенности к коду, который полезен для переключения подструктур или наличия нескольких указателей на одну и ту же подструктуру.Наличие различных мастер-структур, указывающих на общие подструктуры, в частности, может сэкономить немного памяти и время выделения.

0 голосов
/ 28 февраля 2011

Что касается скорости, она меняется.Как правило, включение структур, а не указателей будет быстрее, поскольку ЦПУ не нужно разыменовывать указатель для каждого доступа к элементу.Однако, если некоторые члены используются не очень часто, а размер подструктуры огромен, структура может не помещаться в кэш, и это может немного замедлить ваш код.

Использование указателейбудет использовать / немного / больше памяти (но только размер самих указателей), чем прямой подход.

Обычно с указателями на подструктуры вы выделяете подструктуры отдельно, но вы можете написать некоторыесвоего рода функция инициализации, которая абстрагирует все распределение в «одно и то же время».В вашем коде память выделена для myMainStruct в стеке, но член b будет мусором.Вам нужно вызвать malloc, чтобы выделить память кучи для b, или создать объект subStruct в стеке и указать на него myMainStruct.b.

0 голосов
/ 28 февраля 2011

Память для указателя не будет выделяться автоматически. Вам нужно будет запустить:

myMainStruct.b=malloc(sizeof(*myMainStruct.b));

С точки зрения производительности, вероятно, небольшое попадание при переходе от одной структуры к другой через указатель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...