2010-06-14 13 views

Odpowiedz

30

w C i C++, ZeroMemory() i memset() są dokładnie to samo.

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

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

Dlaczego warto używać ZeroMemory()? To make it obvious. Ale wolę memset() w programach C lub C++.

+2

To jest większy problem, jak zauważyłem w mojej odpowiedzi: optymalizacja kompilatorów może usunąć wywołania 'memset()', więc naprawdę chcesz użyć czegoś, co nie zostanie zoptymalizowane. –

+3

@ richard.albury w takim przypadku powinieneś użyć SecureZeroMemory, ponieważ ZeroMemory może być zoptymalizowane. – ya23

5

Ponieważ interfejs API systemu Windows powinien być agnostykiem językowym. Zapewnia wystarczającą funkcjonalność dla programistów, niezależnie od używanego języka. Oczywiście, w końcu wiele funkcji powiela istniejącą funkcjonalność oferowaną przez języki.

powinien wywoływać funkcje WinAPI (i makr) bezpośrednio, kiedy trzeba pewien poziom kontroli - porównanie fopen() z CreateFile() na przykład. W przeciwnym razie preferuj konstrukcje specyficzne dla języka za pośrednictwem wywołań API. Przynajmniej zyskujesz większą niezależność od platformy.

+3

Nie jestem pewien, w jaki sposób można napisać makro-agnostyczny język. –

+0

ZeroMemory wydaje się być makrem dla krzyżowej nomenklatury w języku MS. Sprawdziłem, jako że prawdopodobnie była to sztuczka systemowa do czyszczenia pamięci sprzętowej, która mogłaby być bardziej wydajna. Jest to prawdopodobnie po prostu syntaktyczny cukier do memsetu; zignoruj ​​to. http://msdn.microsoft.com/en-us/library/aa366920(VS.85).aspx – msw

+1

@Pete: jeśli masz ZeroMemory zdefiniowane w C stdlib i - powiedzmy VBA - to twój koder używa tej samej nazwy dla ten sam cel i jest lepiej zamknięty w Microsoft. Obejmuj i przedłużaj, bracie! http://en.wikipedia.org/wiki/Embrace,_extend_and_extinguish – msw

1

Zgodnie z MSDN, ZeroMemory jest makro. Prawdopodobnie istnieje dla wygody (np. Konwencja nazewnictwa) lub dla kompatybilności wstecznej.

+0

Byłbym kompatybilny z poprzednimi wersjami, wraz z tymi funkcjami do obsługi liczb 32-bitowych (nie pamiętam nazw) dla podziału itp. –

8

ZeroMemory i takie są częścią samego API systemu Windows. memset jest częścią standardowej biblioteki C.

Dla typowego kodu użytkownika normalnie użyłbym memset (lub odpowiednika dostarczonego przez wybrany przez ciebie język). Jeśli piszesz kod jądra (np. Sterownik urządzenia) używając czegoś takiego jak ZeroMemory jest bardziej atrakcyjny. Ponieważ Twój kod jest wykonywany w trybie jądra, nie ponosisz kosztów przełączania zadań, aby go użyć. Ponieważ jest już w kodzie systemu Windows, nie przenosisz dodatkowego kodu do sterownika, aby powielić to, co już jest. W tym samym czasie ponosisz koszt wywołania funkcji, aw przypadku lub zerowania (zwłaszcza w małym bloku) pamięć, kod wewnętrzny może być znacznie szybszy, a kod rep stosd nie zajmuje dużo kodu (w rzeczywistości konfiguracja i używanie rep stosd może zająć mniej kodu niż wywołanie funkcji).

+0

W nowszych kompilatorach Visual Studio 'memset()' jest funkcją wewnętrzną. Oznacza to, że jest on implementowany przez sam kompilator iw wielu przypadkach nie ma wywołania funkcji. Kompilator dodaje do niego specjalnie spreparowany kod zespołu, aby uzyskać najlepsze wyniki w oparciu o docelową architekturę, długość i wyrównanie pamięci nadpisywanych danych. – BJovke

+0

@BJovke: to nie jest ostatnia innowacja. Wraca do co najmniej MS C 6.0 (uwaga: MS C, nie VC++), która (dzieje się dla pamięci, więc może być trochę źle) została wydana około 1989 lub 90. Chyba nie powiedziałem tego wprost w odpowiedzi, ale to było wspomnienie o obciążeniu wywołanym przez funkcję (tzn. Że użycie 'ZeroMemory' wymagałoby wywołania funkcji, ale użycie' memset' często by tego nie zrobiło) . –

3

Bo ZeroMemory nie wymagają linię komentarza

3

Myślę, że jednym z punktów jest to, że funkcje alokacji pamięci powinny wyglądać tak samo we wszystkich projektach Win32, niezależnie od języka programowania. Rzeczywiście, jak już wskazano wcześniej, w C, ZeroMemory jest faktycznie w stanie złożonym, funkcja C. W języku Delphi:

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

gdzie FillChar jest funkcją Delphi. I tak dalej:

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

Naprawdę poza tematem, ale jako programista Delphi, używam MoveMemory (lub CopyMemory - są identyczne), gdy mam wskaźniki, i poruszam się, gdy mam zmienne, więc nie muszę używać "@" lub "^". –

11

Rzeczywista przyczyna jest taka, że ​​na innej platformie może być realizowane w sposób bardziej efektywny niż memset. Nie zapominaj, że Windows NT został zaprojektowany jako wysoce przenośny system operacyjny, faktycznie działający na Alpha, MIPS i Power PC. Tak więc, jeśli platforma fooPC wyszła i ma jakikolwiek sposób montażu do ultraszybkiej pamięci ustawionej na zero, może być zaimplementowana bez zmiany interfejsu API wysokiego poziomu. Nie dotyczy to już systemu Windows, ponieważ teraz obsługuje tylko platformy x86 i amd64, ale nadal jest tak w przypadku systemu Windows CE.

1

W rzeczywistości, do korzystania z usługi jest: SecureZeroMemory().

Kompilator optymalizacyjny może usuwać połączenia pod numer memset(), a SecureZeroMemory() ma na celu zapobieganie temu.

Kiedyś myślałem, że rozmowy ZeroMemory() były niepotrzebne, dopóki nie natknąłem się na ten fakt.

+0

Dodatkowe informacje: https://msdn.microsoft.com/en-us/library/ms972826.aspx – Pang

Powiązane problemy