¿Por qué ZeroMemory y llamadas similares existen en la API de Windows cuando ya hay memset y llamadas relacionadas en la biblioteca estándar de C? ¿A cuáles debo llamar? Adivino que la respuesta es "depende". ¿En que?¿Por qué existen ZeroMemory, etc. cuando ya hay memset, etc.?
Respuesta
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++.
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.
No estoy seguro de cómo escribiría una macro independiente del idioma. –
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
@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
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.
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. –
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).
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
@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) . –
Porque, ZeroMemory no requiere línea de comentario
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;
...
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 "^". –
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.
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.
Referencia adicional: https://msdn.microsoft.com/en-us/library/ms972826.aspx – Pang
- 1. Por qué usar LISP hoy, cuando hay Scala, Erlang, Haskell etc.
- 2. ¿Alguna razón para usar SecureZeroMemory() en lugar de memset() o ZeroMemory() cuando la seguridad no es un problema?
- 3. .Elija, .Activesheet, .Activecell etc ...
- 4. comillas etc
- 5. ¿Por qué NSAssert1, etc. en lugar de NSAssert?
- 6. Agrupación por semana/mes/etc. y ActiveRecord?
- 7. ¿Por qué mDNS (Bonjour, Avahi, etc.) usa UDP?
- 8. ¿Cuál es el tamaño máximo de memoria intermedia que memcpy/memset, etc. puede manejar?
- 9. ¿Dónde declarar estructuras, etc.?
- 10. ¿Qué opciones de color existen para ack (-grep) para la coloración de salida, registros, etc.?
- 11. ¿Se reentrató va_start (etc.)?
- 12. Regex $ 1, $ 2, etc.
- 13. ¿El sistema operativo Android tiene archivos como/etc/passwd,/etc/shadow y/etc/group?
- 14. ¿Por qué no hay continuidad de línea implícita de python en 'y', 'o', etc.?
- 15. ¿Qué significa IB en IBAction, IBOutlet, etc.?
- 16. System.Security.Cryptography.CryptographicException -objeto ya existen
- 17. _mm_load_ps vs. _mm_load_pd vs. etc
- 18. autocompletar, papeles, estrategias, etc
- 19. % temp% etc no funciona
- 20. ¿Son + =, | =, & = etc atómicos?
- 21. tipo de listas, etc.
- 22. Código GPGPU no confiable (OpenCL, etc.): ¿es seguro? ¿Qué riesgos?
- 23. pytz y Etc/GMT-5
- 24. ¿Por qué existen las ID?
- 25. en Scala, largo, int, etc.
- 26. ¿Detener (largo) la consulta SQL en PostgreSQL cuando la sesión o las solicitudes ya no existen?
- 27. conversión de & a & etc
- 28. ¿Por qué Razor no puede ver ViewBag, Url.Content, etc. cuando la página de diseño está fuera ~/Views/Shared?
- 29. botones sin href, onclick, etc.
- 30. ¿Qué estaciones de servicio, restaurantes, etc. están en cierta ciudad?
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. –
@ richard.albury, en ese caso debe usar SecureZeroMemory, ya que ZeroMemory podría optimizarse. – ya23