我不明白引用计数中的内存错误

时间:2014-04-18 17:30:41

标签: c++ valgrind reference-counting

我正在实施一个人为的例子来跟踪引用计数的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)

编辑:请参阅运营商中的注释行=修复。

1 个答案:

答案 0 :(得分:5)

复制赋值运算符需要增加引用计数。