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

时间:2015-04-30 13:00:30

标签: c++ valgrind

我有以下(过于简化)的例子,其中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

用gcc 4.9.2 c ++ 14标志编译并运行valgrind我得到以下输出:

==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) 

这是由于编译器在对象末尾添加了填充(请注意&#34;跨越&#34; 8字节的bool)?如果是这样 - 检查可以做些什么不失败?

1 个答案:

答案 0 :(得分:0)

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

无论是否gmock正在进行转储而不是你,都是如此。