我正在测试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;
}
答案 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
视为算法。