链接方法会导致数据损坏

Chaining methods causes data corruption

本文关键字:数据 损坏 方法 链接      更新时间:2023-10-16

我有一个类结构,看起来有点像这样:

class Bar
{
public:
    Bar & AddPart(int size, const string & name)
    {
        partitions.insert(pair<string, int>(name,size));
        return *this;
    }
    void PrintParts(ostream & os) const
    {
        map<string, int>::const_iterator it;
        for (it = partitions.begin(); it != partitions.end(); ++it)
        {
            os << it->first << " " << it->second << endl;
        }
    }
private:
    std::map<string, int> parts;
}
class Foo
{
public:
    Foo & AddElement(Bar &a)
    {
        elements.push_back(&a);
        return *this;
    }
private:
    vector<Bar *> elements;
};

我返回类的当前实例的原因是能够链方法调用,像这样:

Foo f();
f.AddElement(Bar().AddPart(10,"abcd").AddPart(5,"xyz").AddPart(20, "jklm"));

问题是,当我调用那些链接的方法,然后试图打印数据,它是损坏的。而不是得到预期的输出,它应该看起来像这样:

abcd 10
xyz 5
jklm 20

我得到的是无法显示的随机字符。

我试着通过valgrind运行它,但是我得到了一堆错误,非常类似于这个:

Invalid read of size 8 ==3347== at 0x4EC6690: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)

我该如何解决这个问题?

你的Bar实例在f.AddElement(Bar().AddPart(10,"abcd").AddPart(5,"xyz").AddPart(20, "jklm"));之后被销毁但是你保存了它的指针

再考虑一下,当您将指向右值(Bar())的指针放入elements时:

Foo & AddElement(Bar &a)
{
    elements.push_back(&a); // <--- Here you take address of temporary Bar()
    return *this;
}
f.AddElement(Bar().AddPart(10,"abcd").AddPart(5,"xyz").AddPart(20, "jklm"));