如何创建一个指向矢量的指针向量

时间:2013-04-15 23:40:52

标签: c++ pointers vector

我有一个指向矢量的指针:

vector<double> mv;
mv.push_back(233);
mv.push_back(234);
mv.push_back(654);
vector<double>* new_mv_pt = new vector<double> (3);
new_mv_pt = &mv;    

cout << (*new_mv_pt)[1] << endl;    

如何创建另一个将此指针存储到向量的向量? 我正在尝试这个...

    vector<double*> vop = new vector<double> (3);

vop.push_back(*new_mv_pt);

cout << (*vop)[1] << endl;

但它不起作用。我正在尝试甚至可能吗?:

3 个答案:

答案 0 :(得分:7)

哇,慢下来!

你在记忆中做了一些非常疯狂的事情,所以让我们从头开始。

您有一个包含3个元素的向量。您想使用指针引用该向量。让我们看看它的外观:

vector<double> mv;
mv.push_back(233);
mv.push_back(234);
mv.push_back(654);
// No no no no! You don't have to `new` a pointer that 
// you're going to assign to something else!
// This is called a memory leak, and it means you've just wasted (!!!)
// C++ memory! Don't do it 
// vector<double>* new_mv_pt = new vector<double> (3);
// Instead, do this:
vector<double>* ptr_to_mv = &mv; // No leak, immediately points to a vector<double> mv;

照顾第一位。现在,让我们更深入地了解它。您想要存储向量的引用向量。好吧,这听起来很公平。有几种方法可以解决它。让我们回到mv和其他事情的例子:

vector<double> mv;
mv.push_back(233);
mv.push_back(234);
mv.push_back(654);
vector<double>* ptr_to_mv = &mv;
// So far so good. Now, based on your question, you want
// to have a list of these to point to. So:
vector<vector<double>*> vop;
vop.push_back( ptr_to_mv ); // All clean.

在您的代码中,您必须使用vop.at()访问operator[]才能访问vector<double>*,然后使用{{1}取消引用它或者使用*直接处理它:

->

这会打印233,因为所有这些都是您引用std::vector<double>* ptr_to_vector = vop[0]; // Got my pointer std::cout << ptr_to_vector->at( 0 ) << std::endl; // Prints '233' 的。在另一个答案的评论中,你说当你删除这些指针时,你会得到一个断言。 这应该发生,因为你要删除两次东西!

还记得mv,你很久以前宣称过的吗?好吧,你没有把它变成一个动态矢量。你没有mv它,它不是指针。因此,当函数退出时,它将自动删除自身 - 它将调用其析构函数并且 在堆栈中死亡 。如果你看newptr_to_vector,它们都会引用ptr_to_mv来清理自己。

如果您对其进行了删除操作,那么您正试图在mv上调用删除(这就是您所指向的内容)并且您正在进行双重删除!

所以,当你有一个指向mv的指针时,不要删除它。这是一个基于堆栈的变量。它会清理自己。

仍然关注?好的,让我们进一步了解一下:

现在,如果有一个原因你需要mv向上一个向量,你不要用旧指针指定覆盖它(正如我之前告诉你的那样,你会离开记忆)。你创造了一个全新的指针:

new

上面显示了问题:我们有2个指针,都在// Our vector of double vector pointers vector<vector<double>*> vop; vector<double> mv; mv.push_back(233); mv.push_back(234); mv.push_back(654); // References a stack variable: don't delete vector<double>* ptr_to_mv = &mv; vop.push_back( ptr_to_mv ); // Makes a fresh copy of mv. You must delete this // manually vector<double>* fresh_ptr = new vector<double>( mv ); (*fresh_ptr)[0] = 1337; // changes only data in fresh_ptr, not `mv` vop.push_back( fresh_ptr ); /* Blah blah blah, work */ // Functions about to exit, gotta clean up! delete fresh_ptr; //delete ptr_to_mv; // NO. //delete vop[0]; // NO! //delete vop[1]; // ... Already deleted from fresh_ptr // ... This is going to get tedious if we don't have a fresh_ptr // for every vector we need! 内,其中一个需要通过调用delete来清理,而另一个则不需要,因为它只是对vop的引用,自动清洁!循环向量并删除所有内容将导致令人讨厌的断言发生。我们如何处理它并仍然得到我们需要的清理?

肮脏和快速解决方案1只是mv / delete vop[1]并完成它。更好的解决方案是,无论何时fresh_ptr资源,你都可以将它包装在一个名为std::unique_ptr的奇妙事物中。代码如下所示:

new

然后你去,删除所有注释掉的代码,突然间,你的东西就像吹口哨一样干净!

当然,现在,我的最后一个问题是: 你到底在做什么,需要所有这些指针指向矢量指针的引用?

答案 1 :(得分:3)

是的,但你需要这样做:

vector<vector<double>*> vop;

因为您正在寻找矢量指针列表。

你在这里有什么:

vector<double *> vop

只是double指针的向量。

你也只想要这个:

vop.push_back(new_mv_pt); //  <- No asterisk (you don't want to de-reference it)

答案 2 :(得分:2)

这里有内存泄漏:

vector<double>* new_mv_pt = new vector<double> (3);
new_mv_pt = &mv;

您正在堆上创建vector<double>,将其地址存储在new_mv_pt中,然后覆盖该地址的地址为mvvector<double>仍然存在于堆上,但您已永久丢失其地址(因此无法delete或使用它执行任何其他操作。)

此代码:

vector<double*> vop = new vector<double> (3);
vop.push_back(*new_mv_pt);
cout << (*vop)[1] << endl;

不起作用,因为vopdouble*的向量,并且您正尝试在其中插入vector<double>。有关正确的方法,请参阅Ben's answer