为什么使用这个POD结构作为基类是危险的?

Joh*_*itb 23 c++ pod memset

我和一位同事进行了这次谈话,结果很有趣.假设我们有以下POD课程

struct A { 
  void clear() { memset(this, 0, sizeof(A)); } 

  int age; 
  char type; 
};
Run Code Online (Sandbox Code Playgroud)

clear旨在清除所有成员,设置为0(按字节顺序).如果我们A用作基类会出现什么问题?这里有一个微妙的漏洞来源.

Sta*_*ked 17

编译器可能会向A添加填充字节.因此sizeof(A)延伸到char type(直到填充结束).但是在继承的情况下,编译器可能不会添加填充字节.所以调用memset将覆盖子类的一部分.

  • 你是对的,我认为仅在成员之间添加填充以保持对齐.活到老,学到老.谢谢你!:) (2认同)

Kar*_*tel 5

除了其他注释之外,sizeof是一个编译时运算符,因此clear()不会将派生类添加的任何成员清零(除非由于填充怪异而指出)。

这并没有什么真正“微妙”的地方。memset在 C++ 中使用是一件可怕的事情。在极少数情况下,您确实可以用零填充内存并期望正常的行为,并且您确实需要用零填充内存,通过初始化程序列表对所有内容进行零初始化,文明的方式在某种程度上是不可接受的,请改为使用std::fill