【发布时间】:2014-04-07 10:52:12
【问题描述】:
我见过使用 ZeroMemory 的示例(主要用于 windows 和 directx 结构),但其他时候不使用它。我什么时候应该对结构进行零内存?
【问题讨论】:
我见过使用 ZeroMemory 的示例(主要用于 windows 和 directx 结构),但其他时候不使用它。我什么时候应该对结构进行零内存?
【问题讨论】:
ZeroMemory 只是用 0 填充结构的内存,这本质上意味着结构的每个值都设置为 0。如果在传递之前没有将结构的所有值设置为自定义值,则这是必要的例如 API 函数。创建结构时,每个字段中都有未指定的值 - 这会导致函数中出现未定义的行为,然后访问结构的字段。
【讨论】:
您几乎不应该在 C++ 中这样做,除非您正在编程的某些外部 API 要求您这样做(这可能适用于旧的 Windows C API)。有一些方法可以使用默认构造函数来初始化数据,这样如果内存中的数据类型发生变化,构造就会自动调整。使用ZeroMemory 初始化数据是脆弱的。
有趣的是,微软提到ZeroMemory 甚至可能无法在this documentation for SecureZeroMemory 中工作:
当您想确保您的数据将被及时覆盖时,请使用此函数而不是
ZeroMemory,因为某些 C++ 编译器可以通过完全删除对ZeroMemory的调用来优化它。
【讨论】:
如果您正在创建 C++ 程序,请不要使用 ZeroMemory。使用构造函数和初始化列表来初始化字段。顺便说一句,在 C++11 中,您可以使用以下语法:
struct A {
int x = 0;
int y = -1;
int z = 42;
};
而不是“旧式”
struct A {
int x;
int y;
int z;
A() : x( 0 ), y( -1 ), z( 42 ) {}
};
【讨论】:
ZeroMemory(&a, sizeof(a)) 等于 memset(&a, 0, sizeof(a));。它只是用零填充内存。
但您必须注意a 应该是 POD 数据。也就是说,您不得这样做:
std::string str;
ZeroMemory(&a, sizeof(a)); // never!!
您应该使用 ZeroMemory 和 memset 来处理 POD 数据。 (如果您不了解 POD 数据,它就像 C 样式的结构。)如果您对非 POD 执行 memset,未定义的行为将会出现..
【讨论】:
memset 非 POD,但它会产生未定义的行为。它可能有效,也可能无效,但无论如何,它会生成不可移植且高度脆弱的代码。
that is, you can't this:和// error!!,但你也不能不这样做,也不会产生错误。你完全可以memset C++ 中的所有内容,但在合法 的基础上,这会产生未定义的行为。
当您创建一个结构时(尤其是在使用旧的 Win32 API 遗留代码时),您分配的结构中可能有垃圾,因为这些 Win32 结构没有真正的构造函数。所以这是一种将结构初始化为默认值的方法。
【讨论】:
当有很多值要填写并且零是您对手动设置不感兴趣的部分的有效值时,您将结构归零。抱歉,如果这有点含糊,但基本上就是这样(例如,您有一个充满指针的结构,对于可选值,这些指针允许为 NULL,而您只想设置其中的几个)。
请记住,如果您不将 struct 成员设置为任何内容,在大多数情况下,当您创建它们时,它们会充满垃圾(在 C++ 中,结构可能有一个已经为您处理好这些的构造函数)。
ZeroMemory 虽然是 Windows 的东西,但标准等价物是 memset(ptr,0,size)。在 C++ 中它不是你经常需要的东西,尽管它在 C 中出现了很多(尽管你也可以在 C 中编写类似函数的构造函数,我建议你这样做)。
【讨论】:
它依赖于编译器,新的 gcc 自动将结构归零,但旧的结构具有随机值(根据 maxdev)。
【讨论】: