Warum existieren ZeroMemory und ähnliche Aufrufe in der Windows-API, wenn in der C-Standardbibliothek bereits Memset- und verwandte Aufrufe vorhanden sind? Welche sollte ich anrufen? Ich kann erraten, die Antwort ist "hängt". Auf was?Warum gibt es ZeroMemory usw., wenn bereits ein Memset usw. vorhanden ist?
Antwort
In C und C++, ZeroMemory()
und memset()
sind genau die gleiche Sache.
/* In winnt.h */
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
/* In winbase.h */
#define ZeroMemory RtlZeroMemory
Warum ZeroMemory()
dann verwenden? To make it obvious. Aber ich bevorzuge memset()
in C oder C++ Programme.
Da die Windows-API sprachunabhängig sein sollte. Es bietet ausreichend Funktionalität für Entwickler, unabhängig von der verwendeten Sprache. Natürlich werden viele Funktionen die vorhandenen Funktionen, die von den Sprachen angeboten werden, eventuell duplizieren.
Sie sollten die winapi Funktionen aufrufen (und Makros) direkt, wenn Sie ein gewisses Maß an Kontrolle benötigen - vergleichen fopen()
mit CreateFile()
zum Beispiel. Andernfalls bevorzugen Sie sprachspezifische Konstrukte über API-Aufrufe. Zumindest gewinnen Sie mehr Unabhängigkeit von der Plattform.
Ich bin mir nicht sicher, wie Sie ein sprachunabhängiges Makro schreiben würden. –
ZeroMemory scheint ein Makro für die MS-Sprachen-Nomenklatur zu sein. Ich überprüfte, wie es war möglicherweise ein System-Trick für Hardware-Speicher Clearing, die effizienter hätte sein können. Es ist wahrscheinlich nur syntaktischer Zucker für Memset; ignoriere es. http://msdn.microsoft.com/en-us/library/aa366920(VS.85).aspx – msw
@Pete: Wenn Sie ZeroMemory in der C stdlib definiert haben und - sagen VBA - dann verwendet Ihr Coder den gleichen Namen für der gleiche Zweck und ist besser in Microsoft gesperrt. Umfassen und verlängern, Bruder! http://en.wikipedia.org/wiki/Embrace,_extend_and_extinicish – msw
Nach MSDN ist ZeroMemory ein Makro. Es existiert wahrscheinlich als Annehmlichkeit (z. B. Namenskonvention) oder zur Abwärtskompatibilität.
Ich würde mit der Abwärtskompatibilität gehen, zusammen mit diesen Funktionen für die Behandlung von 32-Bit-Zahlen (ich vergesse die Namen) für die Division etc. –
ZeroMemory
und solche sind Teil des Windows-API selbst. memset
ist Teil der C-Standardbibliothek.
Für typische Benutzerland-Code, würde ich normalerweise memset
(oder das Äquivalent von Ihrer Sprache der Wahl zur Verfügung gestellt). Wenn Sie Kernel-Code schreiben (z. B. einen Gerätetreiber), der etwas wie ZeroMemory
verwendet, ist das attraktiver. Da Ihr Code trotzdem im Kernelmodus ausgeführt wird, entstehen Ihnen keine Kosten für die Verwendung eines Taskswitches. Da es sich bereits im Windows-Code befindet, tragen Sie keinen zusätzlichen Code in Ihrem Treiber mit, um zu kopieren, was bereits vorhanden ist. Gleichzeitig entstehen Ihnen die Kosten eines Funktionsaufrufs, und im Fall oder beim Nullsetzen (insbesondere eines kleinen Blocks) von Arbeitsspeicher kann der Inline-Code erheblich schneller sein, und ein rep stosd
benötigt nicht viel Code (in der Tat, Einrichtung und Verwendung rep stosd
kann weniger Code, der ein Funktionsaufruf).
In neueren Visual Studio-Compiler 'memset()' ist eine intrinsische Funktion. Das bedeutet, dass es vom Compiler selbst implementiert wird und in vielen Fällen kein Funktionsaufruf erfolgt. Der Compiler inline es mit speziellem Assembler-Code, um die besten Ergebnisse zu erzielen, basierend auf Zielarchitektur, Länge und Speicherausrichtung der Daten, die überschrieben werden. – BJovke
@BJovke: Das ist keine besonders neue Innovation. Es geht zurück auf mindestens MS C 6.0 (Anmerkung: MS C, nicht VC++), welches um 1989 oder '90 veröffentlicht wurde (für Speicher, so könnte es ein bisschen falsch sein). Ich denke, ich habe es nicht direkt in der Antwort gesagt, aber das war der Punkt, an dem der Overhead eines Funktionsaufrufs erwähnt wurde (dh, dass 'ZeroMemory' einen Funktionsaufruf beinhaltete, aber' memset' oft nicht) . –
Denn Zeromemory benötigen keine Kommentar-Zeile
Ich denke, ein Punkt ist, dass die Speicherzuordnungsfunktionen das gleiche in allen Win32-Projekten, unabhängig von der Programmiersprache aussehen sollten. In der Tat, wie bereits erwähnt wurde, ist in ZeroMemory tatsächlich die C-Funktion memset. In Delphi,
procedure ZeroMemory(Destination: Pointer; Length: DWORD);
begin
FillChar(Destination^, Length, 0);
end;
wo FillChar die Delphi-Funktion ist. Und so weiter:
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;
...
Wirklich out of topic, aber als Delphi-Entwickler, neige ich dazu, MoveMemory (oder CopyMemory - sie sind identisch), wenn ich Zeiger habe, und Move, wenn ich Variablen habe, so dass ich nicht "@" oder "" verwenden muss^". –
Der eigentliche Grund ist, dass auf einer anderen Plattform könnte es als memset
in einer effizienteren Art und Weise umgesetzt werden. Vergessen Sie nicht, dass Windows NT als sehr portables Betriebssystem entwickelt wurde, es lief tatsächlich auf Alpha, MIPS und Power PC. Also, wenn die fooPC-Plattform herauskam und einen Assembly-Weg zur ultraschnellen Speichereinstellung auf Null hat, kann sie implementiert werden, ohne die High-Level-API zu ändern. Dies gilt nicht mehr für Windows, da es jetzt nur x86- und AMD64-Plattformen unterstützt, es gilt jedoch immer noch für Windows CE.
Eigentlich, was Sie wollen zu verwenden ist SecureZeroMemory()
.
Ein optimierender Compiler kann Aufrufe an memset()
entfernen und SecureZeroMemory()
soll dies verhindern.
Ich dachte, dass die Anrufe ZeroMemory()
unnötig waren, bis ich auf diese Tatsache stieß.
Zusätzliche Referenz: https://msdn.microsoft.com/en-us/library/ms972826.aspx – Pang
- 1. Unterschied zwischen Memset und Zeromemory
- 2. App Engine - warum gibt es PhoneNumber, Link, Rating usw.?
- 3. Gibt es einen Grund, SecureZeroMemory() anstelle von memset() oder ZeroMemory() zu verwenden, wenn Sicherheit kein Problem ist?
- 4. Gibt es plattformunabhängige SQL Query Builder mit Syntax, Logikformatierung usw.?
- 5. Gibt es eine sorted_vector Klasse, die insert() usw. unterstützt?
- 6. Gibt es HTML5/Canvas-Fenstersystembibliotheken (ala Qt, WxWidgets, usw.)?
- 7. Was ist die maximale Größe der Puffer, die memcpy/memset usw. verarbeiten kann?
- 8. Warum verwendet mDNS (Bonjour, Avahi usw.) UDP?
- 9. ORIG_HEAD, FETCH_HEAD, MERGE_HEAD usw.
- 10. Wie finden Sie, ob ein Telefon HDPI, XHDPI usw. ist?
- 11. Wo deklarieren Strukturen usw.?
- 12. Warum ist "01" == "1", "000333" == "333", usw. wahr?
- 13. Netzwerkdiagramm, Word usw.
- 14. Ist die Arbeitseinheit effizienter, wenn mir Transaktionen usw. egal sind?
- 15. Sortierlisten, Suchergebnisse usw.
- 16. Analysieren Twitter Tweets usw.
- 17. size_t, key_t, time_t usw.
- 18. Aerospike: lua udf gibt immer ein leeres Ergebnis zurück, selbst wenn udf ohne Filter zurückfließt usw.
- 19. EditText und TextView usw.
- 20. Xcode Build-Optionen usw. Tutorial
- 21. , Klammern usw. in Atom.io
- 22. JQGrid, Telerik, DataTables usw. Welches ist gut?
- 23. SQLiteException: Tabelle bereits vorhanden ist
- 24. Location.getLatitude usw. ändert sich ständig
- 25. Warum wird der Text in einem -Tag abgeschnitten, auch wenn bereits ein Padding vorhanden ist?
- 26. Schleife der Unterkategorien Unterkategorien usw.
- 27. Was ist mit den Typen int2, int3, float2, float3 usw.
- 28. Xcode sagt Infoplist.strings ist bereits vorhanden, wenn ich Lokalisierungen importiere
- 29. PHP-Sicherheitscheckliste (Injektion, Sitzungen usw.)
- 30. Warum Vergleiche zwischen JPA, Hibernate usw. gemacht werden
Es ist ein größeres Problem, wie ich in meiner Antwort bemerkte: Optimierung Compiler können Aufrufe von 'memset()' entfernen, so dass Sie wirklich etwas verwenden möchten, das nicht weg optimiert wird. –
@ richard.albury in diesem Fall sollten Sie SecureZeroMemory verwenden, da ZeroMemory weg optimiert werden könnte. – ya23