使用 std::make_shared 和虚拟继承时 valgrind 报告的未初始化值

Uninitialized value reported by valgrind when using std::make_shared and virtual inheritance

我有以下(过于简化的)示例,其中 valgrind 抱怨未初始化的内存:

struct B {
  virtual ~B() {}
};
struct BB : public virtual B {
  virtual ~BB() = default;
};
struct BBB : public virtual B {
  virtual ~BBB() {}
};

struct X : public virtual B, public virtual BBB/*, public virtual BB*/ {
  X() { a = 0.0; b = 0.0; c = false;}
  double a;
  double b;
  bool c;
};

并像这样使用它:

auto y = std::make_shared<X>();
HexDump(y.get(), sizeof(X)); // simple hexdump function - similar to gtest output - in real application this is an "uninteresting mock call" where gtest prints binary representation of an object using its size

这里的工作示例:http://coliru.stacked-crooked.com/a/91a54b697010d84b

通过 valgrind 使用 gcc 4.9.2 c++14 标志和 运行 编译它,我得到以下输出:

==58887== Conditional jump or move depends on uninitialised value(s)
==58887==    at 0x93A065: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==58887==    by 0x95E2DA: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==58887==    by 0x9441DC: vsprintf_l (in /usr/lib/system/libsystem_c.dylib)
==58887==    by 0x93464C: sprintf (in /usr/lib/system/libsystem_c.dylib)
==58887==    by 0x100165310: HexDump(void*, unsigned int) (in xxxx)
==58887== Use of uninitialised value of size 8
==58887==    at 0x93A69B: __ultoa (in /usr/lib/system/libsystem_c.dylib)
==58887==    by 0x93A0CC: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==58887==    by 0x95E2DA: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==58887==    by 0x9441DC: vsprintf_l (in /usr/lib/system/libsystem_c.dylib)
==58887==    by 0x93464C: sprintf (in /usr/lib/system/libsystem_c.dylib)
==58887==    by 0x100165310: HexDump(void*, unsigned int) (in xxxxx) 

这是由于编译器在对象末尾添加的填充(注意 "spans" 8 字节的 bool)吗?如果是这样 - 如何才能使检查不失败?

您的示例是未定义的行为,因为 X 不是 POD。因此,以这种方式开始读取随机字节是非法的。要转储对象就转储对象,不要假装转储字节是一回事

无论是否是 gmock 代替您进行转储,这都是正确的。