memset() or value initialization to zero out a struct?(memset() 或值初始化以将结构清零?)
问题描述
在 Win32 API 编程中,通常使用具有多个字段的 C struct
.通常它们中只有几个具有有意义的值,而所有其他值都必须归零.这可以通过以下两种方式之一实现:
In Win32 API programming it's typical to use C struct
s with multiple fields. Usually only a couple of them have meaningful values and all others have to be zeroed out. This can be achieved in either of the two ways:
STRUCT theStruct;
memset( &theStruct, 0, sizeof( STRUCT ) );
或
STRUCT theStruct = {};
第二个变体看起来更干净 - 它是单行的,它没有任何可能输入错误并导致错误的参数.
The second variant looks cleaner - it's a one-liner, it doesn't have any parameters that could be mistyped and lead to an error being planted.
与第一个变体相比,它有什么缺点吗?使用哪种变体?为什么?
Does it have any drawbacks compared to the first variant? Which variant to use and why?
推荐答案
这两个结构的含义非常不同.第一个使用 memset
函数,该函数旨在将内存缓冲区设置为某个值.第二个初始化对象.让我用一点代码解释一下:
Those two constructs a very different in their meaning. The first one uses a memset
function, which is intended to set a buffer of memory to certain value. The second to initialize an object. Let me explain it with a bit of code:
假设您的结构只有 POD 类型的成员(普通旧数据" - 请参阅 什么是 C++ 中的 POD 类型?)
Lets assume you have a structure that has members only of POD types ("Plain Old Data" - see What are POD types in C++?)
struct POD_OnlyStruct
{
int a;
char b;
};
POD_OnlyStruct t = {}; // OK
POD_OnlyStruct t;
memset(&t, 0, sizeof t); // OK as well
在这种情况下,编写 POD_OnlyStruct t = {}
或 POD_OnlyStruct t;memset(&t, 0, sizeof t)
没有太大区别,因为我们这里唯一的区别是 alignment 字节被设置为零值以防 memset
使用.由于您通常无法访问这些字节,因此对您来说没有区别.
In this case writing a POD_OnlyStruct t = {}
or POD_OnlyStruct t; memset(&t, 0, sizeof t)
doesn't make much difference, as the only difference we have here is the alignment bytes being set to zero-value in case of memset
used. Since you don't have access to those bytes normally, there's no difference for you.
另一方面,由于您已将问题标记为 C++,让我们尝试另一个示例,其中成员 类型不同于 POD:
On the other hand, since you've tagged your question as C++, let's try another example, with member types different from POD:
struct TestStruct
{
int a;
std::string b;
};
TestStruct t = {}; // OK
{
TestStruct t1;
memset(&t1, 0, sizeof t1); // ruins member 'b' of our struct
} // Application crashes here
在这种情况下,使用像 TestStruct t = {}
这样的表达式是好的,在它上面使用 memset
会导致崩溃.如果你使用 memset
会发生以下情况 - 创建一个 TestStruct
类型的对象,从而创建一个 std::string
类型的对象,因为它是我们结构的成员.接下来,memset
将对象 b
所在的内存设置为某个值,比如零.现在,一旦我们的 TestStruct 对象超出范围,它将被销毁,当轮到它的成员 std::string b
时,您将看到崩溃,因为该对象的所有内部memset
破坏了结构.
In this case using an expression like TestStruct t = {}
is good, and using a memset
on it will lead to crash. Here's what happens if you use memset
- an object of type TestStruct
is created, thus creating an object of type std::string
, since it's a member of our structure. Next, memset
sets the memory where the object b
was located to certain value, say zero. Now, once our TestStruct object goes out of scope, it is going to be destroyed and when the turn comes to it's member std::string b
you'll see a crash, as all of that object's internal structures were ruined by the memset
.
所以,现实情况是,那些东西是非常不同的,尽管在某些情况下您有时需要将整个结构 memset
归零,但始终重要的是确保您了解自己在做什么,并且不会像我们的第二个示例那样犯错误.
So, the reality is, those things are very different, and although you sometimes need to memset
a whole structure to zeroes in certain cases, it's always important to make sure you understand what you're doing, and not make a mistake as in our second example.
我的投票 - 如果需要,only 对对象使用 memset
,并使用 default 初始化 x = {}
在所有其他情况下.
My vote - use memset
on objects only if it is required, and use the default initialization x = {}
in all other cases.
这篇关于memset() 或值初始化以将结构清零?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:memset() 或值初始化以将结构清零?
基础教程推荐
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01