sis*_*hke 1 c++ inheritance memory-management shared-ptr virtual-destructor
我按照给定的指示尝试解决大学问题.代码编译但会产生关于内存的警告.以下是代码的关键:
#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;
}
Run Code Online (Sandbox Code Playgroud)
main()基本上是来自自动测试的代码,我应该修改程序的其余部分以使main()正常工作.
警告是在派生类*的析构函数定义中报告的,它只是在翻译成英语时说"Bad deallocation".我的问题是:代码中出现此问题的位置和原因是什么?
我删除的代码对内存分配没有影响(我希望),并通过autotesting进行测试,我没有太多访问权限.其中一项测试报告以下内容:
Invalid read of size 8 ...
Address 0x51f0090 is 0 bytes inside a block of size 56 free'd
Run Code Online (Sandbox Code Playgroud)
和
==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
Run Code Online (Sandbox Code Playgroud)
和
==10216== Process terminating with default action of signal 11 (SIGSEGV)
==10216== Bad permissions for mapped region at address 0x0
==10216== at 0x0: ???
Run Code Online (Sandbox Code Playgroud)
如果需要进一步的细节,我可以在这里放一些原始代码.
每次你shared_ptr<ApsClass>(pok)创建一个新的shared_ptr,不知道shared_ptr指向同一个对象的所有其他s.因此,当它shared_ptr被破坏时,它将破坏对象.
但是因为你做了好几次(在你的情况下是两次),对象会不止一次被破坏.
只有shared_ptr从普通指针创建的s才会出现此问题.shared_ptr从另一个创建一个shared_ptr很好.
你应该创建shared_ptr 一次 - 改变它
ApsClass *s = Foo.AddApsClass(new DerivedClass(0.5));
Foo.DelApsClass(s);
Run Code Online (Sandbox Code Playgroud)
对此:
shared_ptr<ApsClass> aps(new DerivedClass(0.5));
shared_ptr<ApsClass> s = Foo.AddApsClass(aps);
Foo.DelApsClass(s);
Run Code Online (Sandbox Code Playgroud)
并改变ApsClass *到shared_ptr<ApsClass> 其他地方.