2017-01-04 6 views
0

私は4つのスマートポインタをそれぞれ含む2つのベクトルがあるいくつかのコードを書いています。私は誤って、第1ベクトルで生成されたイテレータを第2ベクトルの消去メソッドに適用します。その後、プログラムがクラッシュします。私は、コピー構成と移動構成にイレーズ方法が関わっていることを知ります。デバッガに照らして、私は1)nullptrと2つのスマートポインタが第1のベクトルに留まることを理解する。 2)4番目のスマートポインタは2番目のベクトルにあります。 3)いくつかの成功した実行の後にプログラムがクラッシュし始める。私の質問は以下の通りです。ベクター内の消去メソッド

  1. nullptrはどのようにして1番目のベクトルに追加されますか?
  2. イテレータを2番目のベクトルに適用するのはなぜですか?
  3. なぜプログラムは最初からクラッシュしませんか?

私のプラットフォームはXcode 8.1です。事前に感謝します

#include <memory> 
#include <vector> 
#include <iostream> 
#include <string> 

using namespace std; 

class A{ 
public: 
    A(string name_) : name(name_) {cout << name << " construction\n";} 
    const string& get_name() const {return name;} 
    ~A() {cout <<get_name() << " destruction\n";} 
    A (const A& rhs) : name(rhs.name){cout << "A copy constructor\n";} 
    A(A&& rhs) : name(""){ 
     cout <<"A move constructor\n"; 
     swap(rhs); 
    } 
    void swap(A& rhs) noexcept { 
     std::swap(name, rhs.name); 
    } 

private: 
    string name; 
}; 
void foo(); 

int main(){ 
    foo(); 
} 

void foo(){ 
    vector<shared_ptr<A>> vect1, vect2; 
    auto a1 = make_shared<A>("Mike"); 
    auto a2 = make_shared<A>("Alice"); 
    auto a3 = make_shared<A>("Peter"); 
    auto a4 = make_shared<A>("Paul"); 
    vect1.push_back(a1); 
    vect1.push_back(a2); 
    vect1.push_back(a3); 
    vect1.push_back(a4); 
    vect2.push_back(a4); 
    vect2.push_back(a1); 
    vect2.push_back(a2); 
    vect2.push_back(a3); 
    auto it = vect1.begin(); 
    vect1.erase(it); 
    for (auto &c : vect1){ 
     cout << c->get_name() << endl; 
    } 
    vect2.erase(it); 
    for (auto &c : vect2){ 
     cout << c->get_name() << endl; 
    } 
} 
+0

[コンパイルしない](http://coliru.stacked-crooked.com/a/f4cc0aa0aeedef9b) – wally

+0

@Mus campesterコピー&ペーストエラーです。キーワード "const"を追加するだけです。できます。あなたの迅速な対応に感謝。 – William

答えて

1

VS2015では、メッセージではvect2.erase(it);に失敗します。 イテレーターが範囲外です実際それはです。

itの質問には、vect2にも属していません。

プラットフォームで動作する場合でも、未定義の動作です。だから、何かが起こる可能性があります。

あなたはC++標準の中でこれ以上作業していないので、あなたのプラットフォームが実装された方法を扱います(おそらく、イテレータのポインタを使用しています。