Когда вы 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, инициализатор или и то, и другое?

Другие вопросы по тегам