Warum tut ZeroMemory()
, und ähnliche Aufrufe sind in der Windows-API vorhanden, wenn memset und verwandte Aufrufe bereits in der C-Standardbibliothek vorhanden sind? Welche soll ich anrufen? Ich kann mir vorstellen, dass die Antwort “hängt davon ab” lautet. Auf was?
Warum gibt es ZeroMemory usw., wenn es bereits memset usw. gibt?
KannibaleSchmied
In Silico
In C und C++, ZeroMemory()
und memset()
sind genau das gleiche.
/* In winnt.h */
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
/* In winbase.h */
#define ZeroMemory RtlZeroMemory
Warum verwenden ZeroMemory()
dann? Um es deutlich zu machen. Aber ich bevorzuge memset()
in C- oder C++-Programmen.
-
Es ist ein größeres Problem, wie ich in meiner Antwort angemerkt habe: Durch die Optimierung von Compilern können Aufrufe von entfernt werden
memset()
Sie möchten also wirklich etwas verwenden, das nicht wegoptimiert wird.– richard.albury
20. Februar 2013 um 22:12 Uhr
-
@richard.albury in diesem Fall sollten Sie SecureZeroMemory verwenden, da ZeroMemory wegoptimiert werden könnte.
– ja23
31. Juli 2015 um 12:28 Uhr
-
@ya23 Ich hasse es, “naja, eigentlich”, aber genau das habe ich in meiner Antwort gesagt. 😉
– richard.albury
8. August 2019 um 12:35 Uhr
Der eigentliche Grund ist, dass es auf einer anderen Plattform möglicherweise effizienter implementiert wird als memset
. Vergessen Sie nicht, dass Windows NT als äußerst portables Betriebssystem konzipiert wurde, es lief tatsächlich auf Alpha, MIPS und Power PC. Wenn also die fooPC-Plattform herauskam und einen Montageweg zum ultraschnellen Setzen des Speichers 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 noch x86- und amd64-Plattformen unterstützt, aber es gilt immer noch für Windows CE.
-
Ich denke nicht, dass dies der Grund ist. Wenn es einen effizienten Weg zum Nullspeichern gibt, könnten sie diesen in die integrieren
memset
Umsetzung auch.– Maxpm
18. Juni 2018 um 19:56 Uhr
-
@Maxpm in Windows gibt es keine vom System bereitgestellte C-Standardbibliothek. Jede ausführbare Datei verknüpft (häufig statisch) mit der C-Bibliothek, die von ihrem Compiler bereitgestellt wird.
– Lornova
20. Juni 2018 um 7:23 Uhr
ZeroMemory
und solche sind Teil der Windows-API selbst. memset
ist Teil der C-Standardbibliothek.
Für typischen Userland-Code würde ich normalerweise verwenden memset
(oder das Äquivalent, das von der Sprache Ihrer Wahl bereitgestellt wird). Wenn Sie Kernel-Code schreiben (z. B. einen Gerätetreiber), verwenden Sie so etwas wie ZeroMemory
ist attraktiver. Da Ihr Code sowieso im Kernelmodus ausgeführt wird, entstehen Ihnen keine Kosten für einen Taskwechsel, um ihn zu verwenden. Da es bereits im Windows-Code enthalten ist, tragen Sie keinen zusätzlichen Code in Ihrem Treiber mit sich herum, um das zu duplizieren, was bereits vorhanden ist. Gleichzeitig entstehen Ihnen die Kosten für einen Funktionsaufruf, und im Fall des Nullens (insbesondere eines kleinen Speicherblocks) kann Inline-Code erheblich schneller sein, und a rep stosd
erfordert nicht viel Code (tatsächlich das Einrichten und Verwenden rep stosd
kann weniger Code benötigen als ein Funktionsaufruf).
-
In neueren Visual Studio-Compilern
memset()
ist eine Eigenfunktion. Das bedeutet, dass es vom Compiler selbst implementiert wird und in vielen Fällen kein Funktionsaufruf vorhanden ist. Der Compiler fügt es mit speziell gestaltetem Assemblercode ein, um basierend auf der Zielarchitektur, der Länge und der Speicherausrichtung der zu überschreibenden Daten die beste Leistung zu erzielen.– BJovke
26. Januar 2018 um 18:52 Uhr
-
@BJovke: Das ist keine besonders neue Innovation. Es geht mindestens auf MS C 6.0 (Anmerkung: MS C, nicht VC++) zurück, das (wenn es um Speicher geht, also könnte es ein wenig falsch sein) um 1989 oder ’90 veröffentlicht wurde. Ich denke, ich habe es in der Antwort nicht direkt gesagt, aber das war der Punkt, an dem der Overhead eines Funktionsaufrufs erwähnt wurde (dh, dass using
ZeroMemory
würde einen Funktionsaufruf beinhalten, aber mitmemset
oft nicht).– Jerry Sarg
26. Januar 2018 um 22:33 Uhr
Humberto
Weil die Windows-API sprachunabhängig sein sollte. Es bietet ausreichend Funktionalität für Entwickler, unabhängig von der Sprache, die sie verwenden. Natürlich duplizieren viele Funktionen die vorhandene Funktionalität, die von den Sprachen angeboten wird.
Sie sollten die winapi-Funktionen (and Makros) direkt, wenn Sie ein gewisses Maß an Kontrolle benötigen – vergleichen Sie fopen()
mit CreateFile()
zum Beispiel. Ansonsten bevorzugen Sie sprachspezifische Konstrukte gegenüber API-Aufrufen. Zumindest gewinnen Sie mehr Plattformunabhängigkeit.
Eigentlich was du wollen zu verwenden ist SecureZeroMemory()
.
Ein optimierender Compiler kann Aufrufe von entfernen memset()
und SecureZeroMemory()
soll dies verhindern.
Früher dachte ich das ZeroMemory()
Anrufe waren unnötig, bis ich auf diese Tatsache stieß.
Paweł Soltysiak
Weil ZeroMemory keine Kommentarzeile benötigt
Andreas Rejbrand
Ich denke, ein Punkt ist, dass die Speicherzuweisungsfunktionen in allen Win32-Projekten unabhängig von der Programmiersprache gleich aussehen sollten. Wie bereits erwähnt, ist ZeroMemory in C eigentlich Memset, die C-Funktion. In Delphi,
procedure ZeroMemory(Destination: Pointer; Length: DWORD);
begin
FillChar(Destination^, Length, 0);
end;
wobei FillChar die Delphi-Funktion ist. Usw:
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 nicht zum Thema, aber als Delphi-Entwickler neige ich dazu, MoveMemory (oder CopyMemory – sie sind identisch) zu verwenden, wenn ich Zeiger habe, und Move, wenn ich Variablen habe, sodass ich “@” oder “^” nicht verwenden muss “.
– Andreas Rejbrand
14. Juni 2010 um 16:01 Uhr