使用shared_ptr返回向量的指针

时间:2013-07-03 12:00:09

标签: c++ visual-c++ boost

我正在测试vector的shared_ptr。目的很简单,我想返回一个向量指针并访问其中的值。但它给了例外。 “在内存位置的.. std:out_of_range处未处理的异常......”。我正在使用Visual Studio 2012。

vector<int>* func()
{
    boost::shared_ptr<vector<int> > vec(new vector<int>());

    vec->push_back(123);
    return vec.get();
    }

int _tmain(int argc, _TCHAR* argv[])
{
    vector<int>* result = func();

    cout << result->at(0); // ERROR here
    return 0;
}

5 个答案:

答案 0 :(得分:11)

如果要使用共享指针,则返回共享指针,而不是原始指针。否则,当shared_ptr超出范围时,它将破坏向量。访问该向量将导致未定义的行为。

boost::shared_ptr<vector<int> > func()
{
    boost::shared_ptr<vector<int> > vec(new vector<int>());
    vec->push_back(123);
    return vec;
}

但请注意,按值返回向量要好得多:

vector<int> func()
{
    vector<int> vec;
    vec.push_back(123);
    return vec;
}

这样,就没有通过移动构造函数或RVO制作副本。

答案 1 :(得分:1)

您从func()返回的类型必须为boost::shared_ptr<vector<int>> - 而不是vector<int>*

共享指针的重点是你可以随心所欲地传递它们,当它们全部停止被引用时,它们指向的内存被回收。

当您在离开函数时“忘记”对共享指针的引用时,它将自动回收在该点分配的内存 - 为您留下指向无效内存位置的指针。

答案 2 :(得分:1)

您的函数中的shared_ptr是唯一引用vector指针的函数。当它超出范围时(当函数返回时),它因此删除引用的指针。

让你的函数返回shared_ptr而不是常规指针。

答案 3 :(得分:1)

我建议你阅读一下如何使用shared_ptr,因为你做错了。这意味着不再需要处理原始指针,绝对不要混合它们。基本上你像传统的指针一样传递shared_ptr实例,但不必再关心删除它了。这样做:

typedef std::vector< int > my_vector;
typedef boost::shared_ptr< my_vector > my_vector_ptr;

my_vector_ptr func()
{
  my_vector_ptr vec( boost::make_shared< my_vector >() );
  vec->push_back(123);
  return vec.get();
}

int _tmain(int argc, _TCHAR* argv[])
{
  my_vector_ptr result = func();
  cout << result->at(0);
  return 0;
}

答案 4 :(得分:0)

使用后插入器以避免混合插入并返回相同的矢量。让客户指定它的矢量巫婆类型......从而使函数模板能够。

代码:

typedef std::vector< int > my_vector;
typedef boost::shared_ptr< my_vector > my_vector_ptr;

template <typename OutputIterator>
void func1(OutputIterator it)
{
   // std::copy (anotherVector.begin(), anotherVector.end(), it);
   *it++ = 123; 
}

void func2(my_vector& v)
{
   v.push_back(123);
}

int main()
{
    my_vector_ptr vec( new my_vector() );
    func1(std::back_inserter(*vec)); // func is now an algorithm .. 
    func2(*vec);
}

func1中,函数的签名说明了这个函数的作用。你不能从矢量中删除,你不能做任何事情,就像它说的那样。插入

func1视为算法。