从指针到法向量的转换在main内部工作,但在从函数返回时不起作用

时间:2016-11-04 03:58:36

标签: c++

int main() 
{

    vector<int> *v2, v3;
    vector<int> v;
    v.push_back(2);
    v.push_back(1);
    v.push_back(17);
    v.push_back(6);
    vector<vector<int> *> v1;
    v1.push_back(&v);
    v2 = v1.at(0);
    v3 = *v2;
    for (std::vector<int>::iterator i = v3.begin(); i != v3.end(); ++i)
    {
        cout<<*i<<endl;
    }
    return 0;
}

上面的代码按预期工作但当我尝试从函数返回的向量指针列表初始化向量时给出了一个错误

vector<vector<int> *> func()
{
    vector<int> v;
    v.push_back(2);
    v.push_back(1);
    v.push_back(17);
    v.push_back(6);
    vector<vector<int> *> v1;
    v1.push_back(&v);
    return v1;
}
int main() 
{

    vector<int> *v2, v3;
    vector<vector<int> *> v1;
    v1 = func();
    v2 = v1.at(0);
    v3 = *v2;
    for (std::vector<int>::iterator i = v3.begin(); i != v3.end(); ++i)
    {
        cout<<*i<<endl;
    }
    return 0;
}

我不明白上面代码片段中的问题是什么。好心提醒。 错误: 在抛出'std :: bad_alloc'的实例后终止调用 what():std :: bad_alloc 中止(核心倾销)

2 个答案:

答案 0 :(得分:2)

问题是你的函数正在返回一个向量,该向量包含指向另一个本地定义的向量的指针。后者在函数结束时被销毁,因此外部向量中的指针悬空。

vector<vector<int> *> func()
{
    vector<int> v; // this object is destroyed at the end of the function
    v.push_back(2);
    v.push_back(1);
    v.push_back(17);
    v.push_back(6);
    vector<vector<int> *> v1;
    v1.push_back(&v); // DANGER DANGER the pointer &v will dangle
    return v1; 
}

不要在向量中使用指针,除非它是绝对必要的(即使在这种情况下更喜欢使用智能指针,因为它们跟踪所有权)。您可以简单地使用vector<vector<int>>或1D向量并从1D到2D进行映射,反之亦然。后一个选项是首选,因为它保证所有元素都在一个连续的内存区域,因此它是缓存友好的。

答案 1 :(得分:0)

问题在于:

vector<int> v;
//...
v1.push_back(&v);
return v1;

您获取局部变量v的地址并将其返回给调用者。在这一行之后:

v1 = func();

v1[0]中的指针将指向v,它不再存在,因为它已超出范围(func函数)并被销毁。取消引用此指针是undefined behavior,因此您获得badalloc。

此问题至少有两种解决方案。第一种是将v1声明为

vector<vector<int>> v1;

因此,您将返回v副本,放置到v1[0],而不是指向它的指针。

另一种方法是使用指针声明v1并在堆上分配v

vector<int> *v = new vector<int>;
v->push_back(2);
v->push_back(1);
v->push_back(17);
v->push_back(6);
vector<vector<int> *> v1;
v1.push_back(v);

因此v超出范围后,v的内容不会被销毁。但是你不应该忘记在使用后手动删除它,否则你会得到内存泄漏。