web-dev-qa-db-ja.com

memsetなどが既にあるのになぜZeroMemoryなどが存在するのですか?

C標準ライブラリにmemsetおよび関連する呼び出しが既に存在するのに、なぜZeroMemory()および同様の呼び出しがWindowsAPIに存在するのですか?どれに電話すればいいですか?答えは「依存」だと思います。何の上に?

26
CannibalSmith

CとC++では、ZeroMemory()memset()はまったく同じものです。

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

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

では、なぜZeroMemory()を使用するのですか? わかりやすくするために。 しかし、CまたはC++プログラムではmemset()を好みます。

36
In silico

実際の理由は、別のプラットフォームでは、memsetよりも効率的な方法で実装される可能性があるためです。 Windows NTは、移植性の高いオペレーティングシステムとして設計されており、実際にはAlpha、MIPS、およびPowerPCで動作することを忘れないでください。したがって、fooPCプラットフォームが登場し、メモリをゼロに超高速で設定するアセンブリ方法がある場合は、高レベルAPIを変更せずに実装できます。これは、x86およびAMD64プラットフォームのみをサポートするようになったため、Windowsには当てはまりませんが、WindowsCEにも当てはまります。

11
lornova

ZeroMemoryなどはWindowsAPI自体の一部です。 memsetはC標準ライブラリの一部です。

一般的なユーザーランドコードの場合、通常はmemset(または選択した言語で提供される同等のもの)を使用します。 ZeroMemoryのようなものを使用してカーネルコード(デバイスドライバーなど)を作成している場合は、より魅力的です。とにかくコードはカーネルモードで実行されるため、コードを使用するためのタスク切り替えのコストは発生しません。すでにWindowsコードに含まれているため、ドライバーに余分なコードを持ち込んで、既に存在するものを複製する必要はありません。同時に、関数呼び出しのコストが発生します。メモリをゼロ化またはゼロ化(特に小さなブロック)する場合、インラインコードは大幅に高速になる可能性があり、rep stosdは多くのコードを必要としません。 (実際、rep stosdを設定して使用すると、関数呼び出しよりも少ないコードで済む場合があります)。

8
Jerry Coffin

WindowsAPIは言語に依存しない必要があるためです。使用する言語に関係なく、開発者に十分な機能を提供します。もちろん、最終的には多くの機能が言語によって提供される既存の機能を複製します。

特定のレベルの制御が必要な場合はいつでも、winapi関数(およびマクロ)を直接呼び出す必要があります。たとえば、fopen()CreateFile()を比較してください。それ以外の場合は、API呼び出しよりも言語固有の構成を優先します。少なくとも、プラットフォームに依存しないようになります。

6
Humberto

なぜなら、ZeroMemoryはコメント行を必要としないからです

3

1つのポイントは、メモリ割り当て関数は、プログラミング言語に関係なく、すべてのWin32プロジェクトで同じように見える必要があるということです。実際、前に指摘したように、Cでは、ZeroMemoryは実際にはmemset、つまりC関数です。 Delphiでは、

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

ここで、FillCharはDelphi関数です。等々:

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;

...
3

実際、使用したいSecureZeroMemory() です。

最適化コンパイラはmemset()の呼び出しを削除でき、SecureZeroMemory()はこれを防ぐように設計されています。

私は、この事実に出くわすまで、ZeroMemory()呼び出しは不要だと思っていました。

2
richard.albury

[〜#〜] msdn [〜#〜] によると、ZeroMemoryはマクロです。おそらく、利便性(命名規則など)または下位互換性のために存在します。

1
Krumelur