Зачем делать ZeroMemory и т. д. существуют, когда есть memset и т. д. уже?

почему ZeroMemory(), и подобные вызовы существуют в API Windows, когда есть memset и связанные вызовы в стандартной библиотеке C уже? Кому мне позвонить? Я могу догадаться, что ответ "зависит". На чем?

8 ответов


в C и C++, ZeroMemory() и memset() это то же самое.

/* In winnt.h */
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))

/* In winbase.h */
#define ZeroMemory RtlZeroMemory

зачем использовать ZeroMemory() потом? чтобы сделать это очевидным. но я предпочитаю memset() в программах на C или c++.


фактическая причина в том, что на другой платформе она может быть реализована более эффективным способом, чем memset. Не забывайте, что Windows NT была разработана как портативная операционная система, она фактически работала на Alpha, MIPS и Power PC. Таким образом, если платформа fooPC вышла и имеет некоторый способ сборки для сверхбыстрой установки памяти на ноль, ее можно реализовать без изменения API высокого уровня. Это больше не верно для Windows, так как теперь он поддерживает только x86 и amd64 платформы, однако это по-прежнему верно для Windows CE.


ZeroMemory и такие являются частью самого API windows. memset входит в стандартную библиотеку C++.

для типичного кода userland я бы обычно использовал memset (или эквивалент, предоставленный вашим языком). Если вы пишете код ядра (например, драйвер устройства), используя что-то вроде ZeroMemory более привлекательна. Поскольку ваш код все равно выполняется в режиме ядра, вы не берете на себя затраты на его использование. Поскольку он уже находится в коде Windows, вы не ношение дополнительного кода в вашем драйвере, чтобы дублировать то, что уже есть. В то же время вы несете стоимость вызова функции, а в случае или обнуления (особенно небольшого блока) памяти встроенный код может быть значительно быстрее, и A rep stosd не занимает много кода (на самом деле, настройка и использование rep stosd может занять меньше кода, чем вызов функции).


потому что API Windows должен быть языковым агностиком. Он обеспечивает достаточную функциональность для разработчиков, независимо от языка, который они используют. Конечно, в конечном итоге многие функции будут дублировать существующие функции, предлагаемые языками.

вы должны вызвать функции winapi (и макрос) непосредственно всякий раз, когда вам нужен определенный уровень контроля-сравнить fopen() с CreateFile() например. В противном случае предпочитайте языковые конструкции над API звонки. По крайней мере, вы получаете больше независимости от платформы.


потому что ZeroMemory не требует строки комментария


Я думаю, что один момент заключается в том, что функции выделения памяти должны выглядеть одинаково во всех проектах Win32, независимо от языка программирования. Действительно, как указывалось ранее, в C нулевая память на самом деле является memset, функцией C. В Дельфах,

procedure ZeroMemory(Destination: Pointer; Length: DWORD);
begin
  FillChar(Destination^, Length, 0);
end;

где FillChar-это функция Delphi. И так далее:--3-->

procedure MoveMemory(Destination: Pointer; Source: Pointer; Length: DWORD);
begin
  Move(Source^, Destination^, Length);
end;

procedure FillMemory(Destination: Pointer; Length: DWORD; Fill: Byte);
begin
  FillChar(Destination^, Length, Fill);
end;

...

собственно, что ты хочу использовать SecureZeroMemory().

оптимизирующий компилятор может удалить звонки memset() и SecureZeroMemory() предназначен для предотвращения этого.

Я думаю ZeroMemory() звонки были ненужными, пока я не наткнулся на этот факт.


по данным MSDN, ZeroMemory-это макрос. Вероятно, он существует как удобство (например, соглашение об именах) или для обратной совместимости.