2010-06-14 8 views

Antwort

30

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.

+2

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. –

+3

@ richard.albury in diesem Fall sollten Sie SecureZeroMemory verwenden, da ZeroMemory weg optimiert werden könnte. – ya23

5

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.

+3

Ich bin mir nicht sicher, wie Sie ein sprachunabhängiges Makro schreiben würden. –

+0

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

+1

@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

1

Nach MSDN ist ZeroMemory ein Makro. Es existiert wahrscheinlich als Annehmlichkeit (z. B. Namenskonvention) oder zur Abwärtskompatibilität.

+0

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. –

8

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).

+0

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

+0

@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) . –

3

Denn Zeromemory benötigen keine Kommentar-Zeile

3

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; 

... 
+0

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^". –

11

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.

1

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ß.

+0

Zusätzliche Referenz: https://msdn.microsoft.com/en-us/library/ms972826.aspx – Pang

Verwandte Themen