C++ 当已经有memset等时,为什么会存在ZeroMemory等?

C++ 当已经有memset等时,为什么会存在ZeroMemory等?,c++,c,windows,winapi,memset,C++,C,Windows,Winapi,Memset,当C标准库中已经存在memset和相关调用时,为什么Windows API中存在ZeroMemory(),以及类似的调用?我应该给哪一个打电话?我猜答案是“视情况而定”。关于什么?因为Windows API应该与语言无关。它为开发人员提供了足够的功能,无论他们使用何种语言。当然,最终许多函数将复制这些语言提供的现有功能 只要需要某种控制级别,就应该直接调用winapi函数(和宏)——例如,将fopen()与CreateFile()进行比较。否则,更喜欢特定于语言的构造而不是API调用。至少,您获

当C标准库中已经存在memset和相关调用时,为什么Windows API中存在
ZeroMemory()
,以及类似的调用?我应该给哪一个打电话?我猜答案是“视情况而定”。关于什么?

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


只要需要某种控制级别,就应该直接调用winapi函数(和宏)——例如,将
fopen()
CreateFile()
进行比较。否则,更喜欢特定于语言的构造而不是API调用。至少,您获得了更多的平台独立性。

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

ZeroMemory
,这是windows API本身的一部分
memset
是C标准库的一部分


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

因为,ZoMeMeRoice不需要注释,在C和C++中,<> > >代码>零个()/<代码>和<代码> MeMSETE()/<代码>是完全相同的。
/* In winnt.h */
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))

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

那么为什么要使用
ZeroMemory()
?但是我更喜欢C或C++程序中的 MeMSETE()/<代码>。

< P>我想一点是,在所有Win32项目中,内存分配函数应该与编程语言无关。事实上,正如前面所指出的,在C中,ZeroMemory实际上是memset,C函数。在德尔菲

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;

...

实际原因是,在不同的平台上,它可能以比
memset
更有效的方式实现。别忘了Windows NT是作为一个高度可移植的操作系统设计的,它实际上运行在Alpha、MIPS和Power PC上。因此,如果fooPC平台问世,并且有一些汇编方法可以将内存设置为零,那么它可以在不改变高级API的情况下实现。这对Windows不再适用,因为现在它只支持x86和amd64平台,但对Windows CE仍然适用。

实际上,您希望使用的是

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


在我遇到这个事实之前,我一直认为
ZeroMemory()
调用是不必要的。

我不确定如何编写语言不可知的宏。ZeroMemory似乎是跨MS语言命名法的宏。我检查了一下,因为这可能是一个用于硬件内存清除的系统技巧,可能更有效。它可能只是memset的语法糖;别理它@皮特:如果你在C stdlib中定义了ZeroMemory,比如说VBA,那么你的编码器使用相同的名称用于相同的目的,最好锁定在Microsoft中。拥抱并延伸,兄弟@皮特,哎哟!宏与否,它不是Windows API的一部分吗?@Humberto它是Windows API的一部分,但Windows API是用C定义的。为什么你认为Windows API应该是语言不可知的?这真的很离题,但作为一名Delphi开发人员,我在有指针时倾向于使用MoveMemory(或CopyMemory-它们完全相同),当我有变量时移动,所以我不必使用“@”或“^”。我会使用向后兼容性,以及那些用于处理除法的32位数字(我忘记了名称)的函数。这是一个更大的问题,正如我在回答中指出的:优化编译器可以删除对
memset()
的调用,所以你真的想使用一些不会被优化掉的东西。@richard.albury在这种情况下你应该使用SecureZeroMemory,因为ZeroMemory可以被优化掉。@ya23我不想“嗯,实际上”,但这正是我在回答中所说的。;-)在较新的Visual Studio编译器中,
memset()
是一个固有函数。这意味着它是由编译器自己实现的,并且在许多情况下没有函数调用。编译器使用精心编制的汇编代码对其进行内联,以根据被覆盖数据的目标体系结构、长度和内存对齐方式来实现最佳性能。@BJovke:这不是一项特别新的创新。它至少可以追溯到MS C 6.0(注:MS C,而不是VC++),它是在1989年或90年左右发布的(关于内存,所以可能有点错误)。我想我没有在回答中直接说出来,但这就是提到函数调用开销的要点(即,使用
ZeroMemory
会涉及函数调用,但使用
memset
通常不会)。我不认为这是原因。如果存在一种有效的零内存方法,他们也可以将其合并到
memset
实现中。@Maxpm在Windows中没有系统提供的C标准库。每个可执行文件都与编译器提供的C库链接(通常是静态链接)。