我正在实施一个人为的例子来跟踪引用计数的this tutorial:
struct Bar
{
Bar () : refs(1) {}
int x;
int y;
int z;
unsigned refs;
};
class Foo
{
public:
Foo ()
{
bar = new Bar;
bar->x = 5;
bar->y = 10;
bar->z = 15;
}
Foo (const Foo &other) : bar(other.bar)
{
++bar->refs;
}
Foo& operator = (const Foo &other)
{
if (&other != this)
{
if (--bar->refs < 1)
delete bar;
bar = other.bar;
// this would fix it: ++bar->refs;
}
return *this;
}
~Foo ()
{
if (--bar->refs < 1)
delete bar;
}
private:
Bar *bar;
};
int main(void)
{
Foo a;
Foo b = a;
Foo c;
c = b;
}
Valgrind给了我以下错误,虽然没有内存泄露。有人能帮我解释一下吗?
==6814== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 2 from 2)
==6814==
==6814== 1 errors in context 1 of 3:
==6814== Invalid read of size 4
==6814== at 0x400914: Foo::~Foo() (ref-count.cpp:41)
==6814== by 0x4007CA: main (ref-count.cpp:54)
==6814== Address 0x4c2d04c is 12 bytes inside a block of size 16 free'd
==6814== at 0x4A07991: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==6814== by 0x40092E: Foo::~Foo() (ref-count.cpp:42)
==6814== by 0x4007BE: main (ref-count.cpp:52)
==6814==
==6814==
==6814== 1 errors in context 2 of 3:
==6814== Invalid write of size 4
==6814== at 0x400911: Foo::~Foo() (ref-count.cpp:41)
==6814== by 0x4007CA: main (ref-count.cpp:54)
==6814== Address 0x4c2d04c is 12 bytes inside a block of size 16 free'd
==6814== at 0x4A07991: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==6814== by 0x40092E: Foo::~Foo() (ref-count.cpp:42)
==6814== by 0x4007BE: main (ref-count.cpp:52)
==6814==
==6814==
==6814== 1 errors in context 3 of 3:
==6814== Invalid read of size 4
==6814== at 0x40090B: Foo::~Foo() (ref-count.cpp:41)
==6814== by 0x4007CA: main (ref-count.cpp:54)
==6814== Address 0x4c2d04c is 12 bytes inside a block of size 16 free'd
==6814== at 0x4A07991: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==6814== by 0x40092E: Foo::~Foo() (ref-count.cpp:42)
==6814== by 0x4007BE: main (ref-count.cpp:52)
编辑:请参阅运营商中的注释行=修复。
答案 0 :(得分:5)
复制赋值运算符需要增加引用计数。