c++ shared_ptr 继承内存问题 "Bad deallocation"

c++ shared_ptr inheritance memory problems "Bad deallocation"

我尝试按照给定的说明解决大学问题。代码可以编译,但会产生有关内存的警告。这是代码的关键:

#include <iostream>
#include <vector>
#include <memory>    
using std::vector;
using std::shared_ptr;
using std::make_shared;

class ApsClass {
    protected :
        double goose;

    public :
        virtual ~ApsClass() {}
        virtual shared_ptr<ApsClass> clone() const = 0;
        double GetGoose() const { return goose; }
};


class DerivedClass : public ApsClass {
    public :
        ~DerivedClass() {} // Warning here*
        DerivedClass(double goose) { DerivedClass::goose = goose; }
        shared_ptr<ApsClass> clone() const override;
};

shared_ptr<ApsClass> DerivedClass::clone() const {
    return make_shared<DerivedClass>(goose);
}

class Storage {
    vector<shared_ptr<ApsClass>> geese;

    public :
        Storage() {}
        ApsClass *AddApsClass(ApsClass *pok);
        void DelApsClass(ApsClass *pok);
};

ApsClass *Storage::AddApsClass(ApsClass *pok)
{
    // The instructions stated that the object pointed at by pok has no
    // other pointers pointing at it, and should now be "owned" by geese
    geese.push_back(shared_ptr<ApsClass>(pok));
    return pok;
}

void Storage::DelApsClass(ApsClass *pok)
{
    for (int i = 0; i < geese.size(); i++)
        if (geese[i] == shared_ptr<ApsClass>(pok)) {
            geese.erase(geese.begin() + i);
            break;
        }
}

int main ()
{
    Storage Foo;
    ApsClass *s = Foo.AddApsClass(new DerivedClass(0.5));
    Foo.DelApsClass(s);
    return 0;
}

main() 基本上是来自自动测试的代码,我应该修改程序的其余部分以使 main() 正常工作。
警告是在派生的 class* 的析构函数定义中报告的,当翻译成英文时它只是说 "Bad deallocation"。我的问题是:代码中哪里以及为什么会出现这个问题?

我删除的代码对内存分配没有影响(我希望如此),并且是通过自动测试进行测试的,我没有多少访问权限。一项测试报告了以下内容:

Invalid read of size 8 ...  
Address 0x51f0090 is 0 bytes inside a block of size 56 free'd 

==10216== Jump to the invalid address stated on the next line  
==10216== at 0x0: ???  
 Address 0x0 is not stack'd, malloc'd or (recently) free'd

==10216== Process terminating with default action of signal 11 (SIGSEGV)
==10216== Bad permissions for mapped region at address 0x0
==10216== at 0x0: ???

如果需要更多细节,我可以把一些原始代码放在这里。

每次执行 shared_ptr<ApsClass>(pok) 时,您都在创建一个新的 shared_ptr,它不知道指向同一对象的所有其他 shared_ptr。所以当这个 shared_ptr 被销毁时,它会销毁对象。

但是因为你做了几次(在你的情况下是两次)对象被破坏了不止一次。

只有 shared_ptr 从普通指针创建的有这个问题。从另一个 shared_ptr 创建一个 shared_ptr 没问题。

你应该创建一个 shared_ptr 一次 - 改变这个

ApsClass *s = Foo.AddApsClass(new DerivedClass(0.5));
Foo.DelApsClass(s);

对此:

shared_ptr<ApsClass> aps(new DerivedClass(0.5));
shared_ptr<ApsClass> s = Foo.AddApsClass(aps);
Foo.DelApsClass(s);

并将 ApsClass * 更改为 shared_ptr<ApsClass> 其他所有地方