Когда вы ZeroMemory структуры в C++?
Я видел примеры, где используется ZeroMemory (в основном с окнами и структурами directx), но в других случаях он не используется. Когда я должен ZeroMemory структура?
7 ответов
ZeroMemory
просто заполняет память структуры нулями, что по сути означает, что каждое значение структуры установлено в 0. Это необходимо, если вы не устанавливаете все значения структуры в пользовательское значение перед передачей его, например, функции API, При создании структуры в каждом поле есть неопределенные значения - это вызывает неопределенное поведение в функции, которая затем обращается к полям структуры.
Вы почти никогда не должны делать это в C++, если только какой-то внешний API, который вы программируете, просит вас сделать это (что, вероятно, будет для старых API Windows C). Существуют способы инициализации данных с использованием конструкторов по умолчанию, и таким образом, если типы данных, используемые в домах памяти, изменяются, конструкция автоматически корректируется. Использование ZeroMemory
инициализировать данные хрупки.
Интересно, Microsoft упоминает, что ZeroMemory
может даже не работать в этой документации дляSecureZeroMemory
:
Используйте эту функцию вместо
ZeroMemory
когда вы хотите, чтобы ваши данные были быстро перезаписаны, так как некоторые компиляторы C++ могут оптимизировать вызовZeroMemory
удалив его полностью.
Если вы создаете программу на C++, не используйте ZeroMemory. Используйте конструктор и инициализируйте список для инициализации полей. Кстати, в C++11 вы можете использовать этот синтаксис:
struct A {
int x = 0;
int y = -1;
int z = 42;
};
вместо "старого стиля"
struct A {
int x;
int y;
int z;
A() : x( 0 ), y( -1 ), z( 42 ) {}
};
ZeroMemory(&a, sizeof(a))
равно memset(&a, 0, sizeof(a));
, Это просто заполнить память с нуля.
Но вы должны заметить, a
должны быть POD-данные. то есть вы не должны делать это:
std::string str;
ZeroMemory(&a, sizeof(a)); // never!!
Вы должны использовать ZeroMemory
а также memset
к POD-данным. (Если вы не знаете о POD-данных, это похоже на структуру в стиле C.) Если вы делаете memset
для не POD, неопределенное поведение будет приходить..
При создании структуры (особенно при работе со старым унаследованным кодом Win32 API) выделенная структура может содержать мусор, поскольку в этих структурах Win32 нет реального конструктора. Так что это способ инициализации вашей структуры значениями по умолчанию.
Вы обнуляете структуру, когда нужно заполнить много значений, а нули являются допустимыми значениями для частей, которые вы не хотите устанавливать вручную. Извините, если это немного расплывчато, но это в основном так (например, у вас есть структура, полная указателей, которые могут быть NULL
для необязательных значений, и вы хотите установить только пару из них).
Помните, что если вы не устанавливаете элементы структуры на что-либо, в большинстве ситуаций они заполняются мусором при их создании (в C++ структура может иметь конструктор, который уже позаботился об этом за вас).
ZeroMemory
вещь Windows, хотя, стандартный эквивалент memset(ptr,0,size)
, Это не то, что вам часто нужно в C++, хотя оно всплывает в C довольно часто (хотя вы также можете написать конструктор как функции в C, что я бы порекомендовал вам сделать).
Это зависит от компилятора, новые gcc автоматически обнуляют структуры, но более старые имеют случайные значения (согласно maxdev).
взгляните на этот поток: при обнулении структуры, такой как sockaddr_in, sockaddr_in6 и addrinfo перед использованием, что является правильным: memset, инициализатор или и то, и другое?