Я новичок в C (и структурах в C). И я видел разные примеры кода в Интернете, но в чем польза от этого:

void foo(LargeStruct* struct);

Вместо этого

void foo(LargeStruct struct);

Упрощает ли это управление памятью?

2
David 9 Май 2016 в 02:41

3 ответа

Лучший ответ

Первый передает указатель на структуру функции. Последний делает копию структуры и передает ее функции. Если структура большая, создание ее копии для функции является дорогостоящим (требует много ресурсов), поэтому этого следует избегать, если в этом нет необходимости.

5
David Schwartz 9 Май 2016 в 00:21

C передает struct по значению. Это означает, что функция со второй сигнатурой сделает копию всего LargeStruct, чтобы передать ее foo. Это неэкономично с точки зрения использования памяти.

Что еще хуже, выделение LargeStruct будет происходить в автоматической памяти (также известной как «в стеке»). В зависимости от фактического размера вашего struct вызов может быть невозможен в некоторых системах, потому что это вызовет переполнение стека.

С другой стороны, первый подход передает struct по указателю. Размер указателя не зависит от размера LargeStruct.

5
Sergey Kalinichenko 8 Май 2016 в 23:43

Поскольку C передает аргументы по значению, есть два основных момента:

  1. В теле функции вы получите копию переданного параметра, так что в случае void foo(LargeStruct struct); вы получите копию структуры, когда вы изменяете ее члены, она фактически не видна снаружи, потому что это временная копия, которая уничтожается при возврате функции. Поэтому, если вы хотите изменить структуру, вам нужно будет передать указатель на эту структуру.

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

    foo(const LargeStruct *p);

4
Community 20 Июн 2020 в 09:12