2016-09-11 8 views
5

shared_ptrに変換を適用し、クラス内の関数を使用してshared_ptrに格納しようとしています。shared_ptrでベクトルとクラスへの変換

私は、この例で作成しました:これは、セグメンテーション・ダンプを引き起こしhere見ることができるように

#include <vector> 
#include <iostream> 
#include <memory> 
#include <algorithm> 

using namespace std; 

class MyClass { 
public: 
    int factor = 0; 
    MyClass(const int factor_) : factor(factor_) {} 

    shared_ptr<vector<int> > mult(shared_ptr<vector<int> > numbers) { 
     shared_ptr<vector<int> > result(new vector<int>()); 

     transform(numbers->begin(), numbers->end(), result->begin(), 
      [this](int x){ return factor * x; }); 

     return result; 
    } 
}; 

int main() 
{ 
    shared_ptr<vector<int> > numbers(new vector<int>()); 
    shared_ptr<vector<int> > res(new vector<int>()); 
    MyClass times_two(2); 

    numbers->push_back(1); 
    numbers->push_back(2); 
    numbers->push_back(3); 

    res = times_two.mult(numbers); 

    cout << "{"; 
    for (unsigned int i = 0; i < res->size(); ++i) 
     cout << res->at(i) << ", "; 
    cout << "}";  

    return 0; 
} 

を。出力が{2, 4, 6, }になるようにこれを解決する方法についての助け?

ラムダを使用することに注意してください。これは、私が完全実装で必要とするためです。

私はあなたが新しい、空のベクターを構築し、交換することも

transform((*numbers).begin(), (*numbers).end(), (*result).begin(), 
     [this](int x){ return factor * x; }); 

答えて

4
shared_ptr<vector<int> > result(new vector<int>()); 

transform(numbers->begin(), numbers->end(), result->begin(), 
     [this](int x){ return factor * x; }); 

を試してみました。 resultので

transform(numbers->begin(), numbers->end(), result->begin(), 
     [this](int x){ return factor * x; }); 

終了イテレータ値を返しresult->begin()、空です。 std::transformは入力シーケンスをコピーし、変換ラムダを適用し、変換された結果を出力イテレータに書き込みます。

ベクトルが空であるため、書き込むものはありません。空の配列の最後を過ぎて実行しているため、未定義の動作とメモリの破損が発生します。この場合

、あなたはその大きさは、事前に、どうあるべきかを知っているので、単純に、出力配列を事前に割り当て:

shared_ptr<vector<int> > result(new vector<int>(numbers->size())); 

さて、これは正しいサイズの出力配列を作成します、begin()が返されます配列の先頭にイテレーターがあり、std::transform()は配列の上を喜んでくたびれます。

あなたが本当にちょうどそれが上書き持っている、あなたは、代わりに渡すので、出力イテレータのためstd::back_insert_iteratorを使用し、配列の最終的なサイズを事前に割り当てるreserve()を使用することができ、値が初期化新しい配列の余分なオーバーヘッドを回避したい場合begin()にあります。

+0

ありがとうございます!それは動作します。私は 'reserve'と' back_inserter() 'を使いました。解決策は[ここ](http://coliru.stacked-crooked.com/a/188945e985a51137)で見つけることができます。 – Stereo

関連する問題