Ці дві конструкції дуже різні за своїм значенням. Перший використовує memset
функцію, яка призначена для встановлення буферу пам'яті певного значення . Другий, який ініціалізує об’єкт . Дозвольте пояснити це трохи коду:
Припустимо, у вас є структура, яка містить лише членів типів POD ("Звичайні старі дані" - див. Що таке типи POD у C ++? )
struct POD_OnlyStruct
{
int a;
char b;
};
POD_OnlyStruct t = {};
POD_OnlyStruct t;
memset(&t, 0, sizeof t);
У цьому випадку написання POD_OnlyStruct t = {}
або POD_OnlyStruct t; memset(&t, 0, sizeof t)
не має великої різниці, оскільки єдина різниця, яку ми маємо тут, - це байти вирівнювання, які встановлюються на нульове значення у випадку memset
використання. Оскільки ви зазвичай не маєте доступу до цих байтів, для вас немає різниці.
З іншого боку, оскільки ви позначили своє запитання як C ++, спробуймо ще один приклад із типами членів, відмінними від POD :
struct TestStruct
{
int a;
std::string b;
};
TestStruct t = {};
{
TestStruct t1;
memset(&t1, 0, sizeof t1);
}
У цьому випадку використання виразу like TestStruct t = {}
- це добре, а використання memset
on - призведе до аварії. Ось що трапляється, якщо ви використовуєте memset
- створюється об’єкт типу TestStruct
, таким чином створюється об’єкт типу std::string
, оскільки він є членом нашої структури. Далі memset
встановлює пам’ять, де b
знаходився об’єкт, на певне значення, скажімо нуль. Тепер, як тільки наш об'єкт TestStruct виходить за межі області його використання, він буде знищений, і коли черга прийде до його учасника, std::string b
ви побачите збій, оскільки всі внутрішні структури цього об'єкта були зруйновані memset
.
Отже, реальність така, що ці речі дуже різні , і хоча іноді вам потрібно memset
в цілому структуру до нулів у певних випадках, завжди важливо переконатися, що ви розумієте, що робите, і не помилятися, як у нашому другому приклад.
Мій голос - використовувати memset
на об’єктах лише якщо це потрібно, а в усіх інших випадках використовувати ініціалізацію за замовчуваннямx = {}
.