2017-02-08 8 views
0

shared_ptrsとQStringsをテストしていますが、完全に理解できないクラッシュがあります。コードは次のとおりです。shared_ptrにアクセスするとプログラムがクラッシュするQStringを保持

#include <QCoreApplication> 
#include <QString> 

#include <iostream> 

class Base { 
public: 
    Base(const QString& str1, const QString& str2, const QString& str3) { 
    member1_ = std::make_shared<Internal>(); 
    (*member1_).i1 = str1; 
    (*member1_).i2 = str2; 
    member2_ = std::make_shared<QString>(str3); 
} 
QString getMember() { return *member2_; } 
QString getInternalMember() { return (*member1_).i1; } 
protected: 
Base(const Base&) = default; 
Base& operator=(const Base&) = default; 
Base(Base&&) = default; 
Base& operator=(Base&&) = default; 

private: 
struct Internal { 
    QString i1; 
    QString i2; 
}; 
std::shared_ptr<Internal> member1_; 
std::shared_ptr<QString> member2_; 
}; 

class Derived : public Base { 
public: 
    Derived(const QString& str1, const QString& str2, const QString& str3) : Base(str1, str2, str3) { 
    derivedMember_ = 1; 
    } 
private: 
    int derivedMember_; 
}; 

int main(int argc, char *argv[]) { 
QCoreApplication a(argc, argv); 
Derived* d1 = new Derived("param1", "param2", "param3"); 
std::cout << "d1 created " << d1->getMember().toStdString() << "-" << d1->getInternalMember().toStdString() << std::endl; 
Derived* d2 = d1; 
delete d1; 
std::cout << "d2 created " << d2->getMember().toStdString() << "-" << d2->getInternalMember().toStdString() << std::endl; 
return a.exec(); 
} 

なぜこれがクラッシュしますか?私はshared_ptrsを使用しているので、代入参照カウンタをインクリメントする必要があります。

D1と同じオブジェクトへの事前のおかげで

+0

あなたはポインタではなく、オブジェクトをコピーします。 –

+0

QStringは[COW](https://en.wikipedia.org/wiki/Copy-on-write)を使用しているので、なぜこのような状況にいるのかは不明です。スマートポインタの使用には価値がほとんどありません。 – MrEricSir

+0

@MrEricSirすべてのコピーされたオブジェクトに対してQStringを同じにします。 QStringが普通のポインタを使ってCOWを使っていても、それを修正すればコピーされ、オブジェクトは異なる値を持ちます – RuLoViC

答えて

3

D2ポイントは、あなたがオブジェクトを削除してから(削除後)にそのメソッドを呼び出してみてください

+0

この場合、QStringをintで変更するとクラッシュしませんか? – RuLoViC

+1

これは未定義の動作です。 –

関連する問題