2016-09-11 85 views
5

我想將變換應用於shared_ptr並存儲到shared_ptr,同時也使用類中的函數。C++ 11與shared_ptr轉換爲向量和類

我建立這個例子:

#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; 
} 

如可以看到的here這導致分段轉儲。任何幫助我如何解決這個問題,這樣的輸出產量{2, 4, 6, }

請注意,我使用lambda,因爲我需要它在我的完整實現。

我也試過更換,

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

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是空的,result->begin()返回結束迭代器值。 std::transform複製輸入序列,應用轉換lambda,並將轉換結果寫入輸出迭代器。

由於向量是空的,所以沒有什麼可寫的。您正在經過空數組的末尾,導致未定義的行爲和內存損壞。

在這種情況下,只需預先分配輸出數組,因爲你知道它的大小應該是什麼,提前:

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

現在,這將創建正確尺寸的輸出數組,begin()將返回迭代器到數組的開頭,並且std::transform()將愉快地在數組上塗寫。

如果您確實希望避免額外初始化新陣列的額外開銷,您可以使用reserve()預先分配陣列的最終大小,然後將std::back_insert_iterator用於輸出迭代器,而不是傳遞在begin()

+0

謝謝!這樣可行。我用'reserve'和'back_inserter()'。解決方案可以在這裏找到(http://coliru.stacked-crooked.com/a/188945e985a51137)。 – Stereo