1

我正在使用vector的shared_ptr进行测试。目的很简单,我想返回一个vector的指针并访问其中的值。但它给出了例外。“未处理的异常在.. 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;
}
4

5 回答 5

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进行复制。

于 2013-07-03T12:03:11.807 回答
1

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

共享指针的全部意义在于您可以随意传递它们,并且当它们都停止被引用时,它们指向的内存将被回收。

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

于 2013-07-03T12:03:47.933 回答
1

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

使您的函数返回 ashared_ptr而不是常规指针。

于 2013-07-03T12:04:28.403 回答
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;
}
于 2013-07-03T12:04:32.877 回答
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其视为一种算法。

于 2013-07-03T12:56:05.150 回答