2010-06-14 15 views

Respuesta

30

En C y C++, y ZeroMemory()memset() son exactamente lo mismo.

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

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

¿Por qué usar ZeroMemory() luego? To make it obvious. Pero prefiero memset() en programas C o C++.

+2

Es un problema mayor, como noté en mi respuesta: la optimización de los compiladores puede eliminar llamadas a 'memset()', por lo que realmente desea usar algo que no se optimice. –

+3

@ richard.albury, en ese caso debe usar SecureZeroMemory, ya que ZeroMemory podría optimizarse. – ya23

5

Porque la API de Windows debe ser independiente del idioma. Proporciona suficiente funcionalidad para los desarrolladores, independientemente del idioma que usen. Por supuesto, eventualmente muchas funciones duplicarán la funcionalidad existente ofrecida por los idiomas.

usted debe llamar a las funciones WinAPI (y macros ) directamente cada vez que necesita un cierto nivel de control - comparar fopen() con CreateFile() por ejemplo. De lo contrario, prefiera construcciones específicas del lenguaje a través de llamadas API. Al menos, ganas más independencia de la plataforma.

+3

No estoy seguro de cómo escribiría una macro independiente del idioma. –

+0

ZeroMemory parece ser una macro para la nomenclatura cruzada del lenguaje MS. Lo comprobé, ya que posiblemente fue un truco del sistema para borrar la memoria del hardware, que podría haber sido más eficiente. Probablemente sea solo azúcar sintáctico para mí; ignoralo. http://msdn.microsoft.com/en-us/library/aa366920(VS.85).aspx – msw

+1

@Pete: si tiene ZeroMemory definido en C stdlib y, por ejemplo, VBA, su codificador usa el mismo nombre para el mismo propósito y está mejor encerrado en Microsoft. ¡Abraza y extiende, hermano! http://en.wikipedia.org/wiki/Embrace,_extend_and_extinguish – msw

1

De acuerdo con MSDN, ZeroMemory es una macro. Probablemente existe como una conveniencia (por ejemplo, convención de nomenclatura) o por compatibilidad con versiones anteriores.

+0

Me gustaría ir con la compatibilidad hacia atrás, junto con esas funciones para el manejo de números de 32 bits (Olvidé los nombres) para la división, etc. –

8

ZeroMemory y tales son parte de la API de Windows. memset es parte de la biblioteca estándar de C.

Para el código de usuario típico, normalmente usaría memset (o el equivalente proporcionado por el idioma de su elección). Si está escribiendo código de kernel (por ejemplo, un controlador de dispositivo) usando algo como ZeroMemory es más atractivo. Dado que su código se ejecuta en modo kernel de todos modos, no incurre en el costo de un cambio de tarea para usarlo. Dado que ya está en el código de Windows, no tiene un código adicional en su controlador para duplicar lo que ya está allí. Al mismo tiempo, incurre en el costo de una llamada a función, y en el caso o en la puesta a cero (especialmente en un pequeño bloque de memoria), el código en línea puede ser significativamente más rápido, y un rep stosd no requiere mucho código (de hecho, la configuración y el uso de rep stosd pueden tomar menos código que una llamada a función).

+0

En los compiladores de Visual Studio más nuevos 'memset()' es una función intrínseca. Eso significa que es implementado por el propio compilador y en muchos casos no hay llamada de función. El compilador lo inscribe con un código de ensamblaje especialmente diseñado para obtener el mejor rendimiento en función de la arquitectura de destino, la longitud y la alineación de la memoria de los datos que se sobrescriben. – BJovke

+0

@BJovke: esa no es una innovación particularmente reciente. Se remonta al menos a MS C 6.0 (nota: MS C, no VC++), que (pasando por la memoria, por lo que podría estar un poco mal) fue lanzado alrededor de 1989 o '90. Supongo que no lo dije directamente en la respuesta, pero ese fue el punto de mencionar la sobrecarga de una llamada de función (es decir, que usar 'ZeroMemory' implicaría una llamada a función, pero usar' memset' a menudo no lo haría) . –

3

Porque, ZeroMemory no requiere línea de comentario

3

Creo que un punto es que las funciones de asignación de memoria deben ser iguales en todos los proyectos de Win32, independientemente del lenguaje de programación. De hecho, como se ha señalado anteriormente, en C, ZeroMemory es realmente memset, la función C. En Delphi,

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

donde FillChar es la función Delphi. Y así sucesivamente:

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; 

... 
+0

Realmente fuera de tema, pero como desarrollador de Delphi, tiendo a usar MoveMemory (o CopyMemory - son idénticos) cuando tengo punteros, y Move cuando tengo variables, así que no tengo que usar "@" o "^". –

11

La razón real es que en una plataforma diferente que podría ser implementado de una manera más eficiente que memset. No olvide que Windows NT fue diseñado como un sistema operativo altamente portátil, en realidad se ejecutaba en Alpha, MIPS y Power PC. Por lo tanto, si la plataforma fooPC salió y tiene algún modo de ensamblaje para configurar la memoria ultrarrápida a cero, puede implementarse sin cambiar la API de alto nivel. Esto ya no es así para Windows, ya que ahora solo admite plataformas x86 y amd64, sin embargo, sigue siendo cierto para Windows CE.

1

En realidad, lo que quiere para usar es SecureZeroMemory().

Un compilador de optimización puede eliminar llamadas a memset(), y SecureZeroMemory() está diseñado para evitar esto.

Solía ​​pensar que las llamadas ZeroMemory() no eran necesarias hasta que me enteré de este hecho.

+0

Referencia adicional: https://msdn.microsoft.com/en-us/library/ms972826.aspx – Pang

Cuestiones relacionadas