Convert C ++ 11 with shared_ptr to vector and class

I am trying to apply a conversion to shared_ptr and save to shared_ptr , and also use a function in the class.

I created this example:

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

As you can see here , this leads to a segmentation dump. Any help on how I can resolve this so that the output gives {2, 4, 6, } ?

Please note that I use lambda because I need it in my full implementation.

I also tried replacing,

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

with

 transform((*numbers).begin(), (*numbers).end(), (*result).begin(), [this](int x){ return factor * x; }); 
+5
source share
1 answer
  shared_ptr<vector<int> > result(new vector<int>() ); 

You create a new empty vector.

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

Since result empty, result->begin() returns the value of the final iterator. std::transform copies the input sequence, applies the lambda transform, and writes the converted result to the output iterator.

Since the vector is empty, there is nothing to write. You run through the end of an empty array, which leads to undefined behavior and memory corruption.

In this case, just predefine the output array, since you know what its size is, in advance:

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

Now this will create an output array of the correct size, begin() will return the iterator to the beginning of the array, and std::transform() happily scratch the array.

If you really want to avoid the additional overhead of initializing a new array, just to overwrite it, you can use reserve() to pre-allocate the final size of the array, and then use std::back_insert_iterator for the output iterator, instead of passing to begin() .

+4
source

All Articles