使用用户定义的默认构造函数对普通结构进行 memset 是否安全?

Che*_* OT 5 c++

我知道如果一个 C++ 结构是普通旧数据(“POD”),那么这保证了它的内存结构中没有魔法,所以这意味着 amemcpy到一个字节数组并且memcpyback 是安全的。

我也知道在标准中 POD 结构不应该有用户定义的构造函数。在我现在拥有的项目中,有一些普通结构(只有数据字段),定义了一个默认构造函数,将数据成员初始化为 0。我看到其他客户端memset(&obj, 0, sizeof obj);在使用该结构之前会使用。

memset在使用非 POD 结构之前,它是否可以或安全?

R S*_*ahu 3

拥有构造函数并不意味着struct非 POD。

如果聚合类没有用户定义的复制赋值运算符和析构函数,并且其非静态成员都不是非 POD 类、非 POD 数组或引用,则该聚合类称为 POD。

鉴于此,拨打电话是完全安全的

memset(&obj, 0, sizeof obj);
Run Code Online (Sandbox Code Playgroud)

在 a 的对象上,struct只要它是一个 POD,它就有一个构造函数。

好不好,就看情况了。如果 的默认构造函数希望struct将成员初始化为1正常行为,则上述调用memset可能会影响依赖于以下代码的行为:1可能会影响依赖于默认值的

举个例子struct

struct Direction
{
   Direction() : x(1.0), y(0.0), z(0.0) {}
   double x;
   double y;
   double z;
};
Run Code Online (Sandbox Code Playgroud)

类型的对象Direction期望至少其中一个组件不为零。当所有分量都为零时,您无法定义方向。如果您将memset所有内容设置为0,代码可能会损坏。

编辑 从下面的注释来看,POD 的定义似乎已从 C++03 更改为 C++11。

memset(&obj, 0, sizeof obj);毕竟使用可能并不安全。

  • @RSahu 你引用的答案说它基于“C++ 标准 (C++03 9 §4)” - 我引用 C++11,最终草案。事情可能已经改变了。更一般地说,问题是要了解两件事:1)“memcpy”是否安全 - 在编译时使用 [is_trivially_copiable](http://en.cppreference.com/w/cpp/types/is_trivially_copyable 可以更好地断言)而不是由程序员推断一次,并希望维护编程不会破坏它,2)如果“memset()”是安全的:我怀疑它是否可移植,甚至对于 POD - 例如,所有 0 位可能对某些奇怪的东西无效`float`/`double` 表示。 (2认同)
  • @TonyD:确实,区分 `memcpy` 和 `memset` 很重要! (2认同)