既然已经有了memset等,为什么还要存在ZeroMemory等呢?

发布于 2024-09-05 05:20:13 字数 113 浏览 17 评论 0原文

当 C 标准库中已经有 memset 和相关调用时,为什么 Windows API 中还存在 ZeroMemory() 和类似的调用?我应该打电话给哪些人?我猜答案是“取决于”。靠什么?

Why does ZeroMemory(), and similar calls exist in the Windows API when there are memset and related calls in the C standard library already? Which ones should I call? I can guess the answer is "depends". On what?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

红尘作伴 2024-09-12 05:20:14

在 C 和 C++ 中,ZeroMemory()memset() 是完全相同的东西。

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

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

那么为什么要使用 ZeroMemory() 呢? 为了使其显而易见。但我更喜欢 memset( ) 在 C 或 C++ 程序中。

In C and C++, ZeroMemory() and memset() are the exact same thing.

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

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

Why use ZeroMemory() then? To make it obvious. But I prefer memset() in C or C++ programs.

小忆控 2024-09-12 05:20:14

真正的原因是,在不同的平台上,它可能会以比 memset 更有效的方式实现。不要忘记Windows NT被设计为高度可移植的操作系统,它实际上运行在Alpha、MIPS和Power PC上。因此,如果 fooPC 平台问世并具有某种组装方法可以超快速地将内存设置为零,则可以在不更改高级 API 的情况下实现它。对于 Windows 来说,情况不再如此,因为现在它仅支持 x86 和 amd64 平台,但对于 Windows CE 来说仍然如此。

The actual reason is that on a different platform it might be implemented in a more efficient way than memset. Don't forget that Windows NT was designed as a highly portable operating system, it actually ran on Alpha, MIPS and Power PC. So, if the fooPC platform came out and has some assembly way to ultra-fast set memory to zero, it can be implemented without changing the high level API. This is no longer true for Windows, since now it only supports x86 and amd64 platforms, however it is still true for Windows CE.

情仇皆在手 2024-09-12 05:20:14

ZeroMemory 等是 Windows API 本身的一部分。 memset 是 C 标准库的一部分。

对于典型的用户层代码,我通常会使用 memset (或您选择的语言提供的等效项)。如果您正在编写内核代码(例如,设备驱动程序),那么使用 ZeroMemory 之类的东西会更有吸引力。由于您的代码无论如何都在内核模式下执行,因此您不会因为使用它而产生任务切换的成本。由于它已经存在于 Windows 代码中,因此您无需在驱动程序中携带额外的代码来复制已有的代码。同时,您确实会产生函数调用的成本,并且在内存归零(尤其是一小块)的情况下,内联代码可能会明显更快,而 rep stosd 则不会。不需要太多代码(事实上,设置和使用rep stosd 可能比函数调用需要更少的代码)。

ZeroMemory and such are part of the windows API itself. memset is part of the C standard library.

For typical userland code, I'd normally use memset (or the equivalent provided by your language of choice). If you're writing kernel code (e.g., a device driver) using something like ZeroMemory is more attractive. Since your code executes in kernel mode anyway, you don't incur the cost of a task switch to use it. Since it's already in the Windows code, you aren't carrying around extra code in your driver to duplicate what's already there. At the same time, you do incur the cost of a function call, and in the case or zeroing (especially a small block of) memory, inline code may be significantly faster, and a rep stosd doesn't take much code (in fact, setting up and using rep stosd may take less code that a function call).

情域 2024-09-12 05:20:14

因为 Windows API 应该与语言无关。它为开发人员提供了足够的功能,无论他们使用哪种语言。当然,最终许多功能将复制这些语言提供的现有功能。

当您需要一定程度的控制时,您应该直接调用 winapi 函数(和宏)——将 fopen()CreateFile() 进行比较例如。否则,与 API 调用相比,更喜欢特定于语言的构造。至少,您获得了更多的平台独立性。

Because the Windows API should be language-agnostic. It provides sufficient functionality for developers, regardless of the language they use. Of course, eventually many functions will duplicate existing functionality offered by the languages.

You should call the winapi functions (and macros) directly whenever you need a certain level of control -- compare fopen() with CreateFile() for instance. Otherwise, prefer language-specific constructs over API calls. At least, you gain more platform-independence.

煞人兵器 2024-09-12 05:20:14

实际上,您想要使用的是SecureZeroMemory()

优化编译器可以删除对 memset() 的调用,而 SecureZeroMemory() 旨在防止这种情况发生。

我曾经认为 ZeroMemory() 调用是不必要的,直到我发现这个事实。

Actually, what you want to use is SecureZeroMemory().

An optimizing compiler can remove calls to memset(), and SecureZeroMemory() is designed to prevent this.

I used to think the ZeroMemory() calls were unnecessary until I came across this fact.

最笨的告白 2024-09-12 05:20:14

因为,ZeroMemory 不需要注释行

Because, ZeroMemory don't require line of comment

七秒鱼° 2024-09-12 05:20:14

我认为有一点是,内存分配函数在所有 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;

...

I think one point is that the memory allocation functions should look the same in all Win32 projects, independent of the programming language. Indeed, as have been pointed out before, in C, ZeroMemory is actually memset, the C function. In Delphi,

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

where FillChar is the Delphi function. And so on:

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;

...
顾铮苏瑾 2024-09-12 05:20:14

根据 MSDN, ZeroMemory 是一个宏。它的存在可能是为了方便(例如,命名约定)或向后兼容。

According to MSDN, ZeroMemory is a macro. It probably exists as a convenience (e.g., naming convention) or for backwards compatibility.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文