我有一个名为Foo的类,它有一个成员,指向另一个名为Bar的类的指针向量。我在构造函数中初始化它但我不确定如何在析构函数中释放它。我还在学习。非常感谢你的帮助。拥有此成员的原因是范围超出该方法,即超出堆栈。感谢。
#include <iostream>
#include <vector>
using namespace std;
class Bar {};
class Foo {
public:
Foo() {
bars = new vector<Bar*>*[10];
for (int i = 0; i < 10; i++) {
bars[i]->push_back(new Bar());
}
}
~Foo () {
for (int i = 0; i < 10; i++) {
// TODO: how to clean up bars properly?
}
}
private:
vector<Bar*>** bars;
};
int main () {
new Foo();
return 0;
}
更新:我感谢所有方面的反馈。我是C和C ++的新手。基本上我想要一个2d结构作为类成员,它将在类的生命周期中持续存在。外部结构是阵列的原因是因为我知道它需要多大。否则我以前使用矢量矢量。
答案 0 :(得分:2)
甚至没有正确分配。您为std::vector<Bar*>
分配了一组指针,但从未分配任何std::Vector<Bar*>
。
最好的办法就是std::vector<std::unique_ptr<Bar>>
甚至std::unique_ptr<std::vector<std::unique_ptr<Bar>>>
之类的东西。你得到的只是WTF。
或std::unique_ptr<std::array<std::unique_ptr<std::vector<std::unique_ptr<Bar>>>, 10>>
。这是完全匹配(但是自我清理)。
答案 1 :(得分:1)
指针的数量有点荒谬,因为他们所做的只是导致混乱和泄漏,从非正确的初始化和问题的标题可以看出。你根本不需要任何指针,也不必担心任何清理。
对于第一维传递到构造函数的2D数组,可以使用向量向量:
std::vector<std::vector<Bar>> bars;
要使用传入的大小初始化外部向量,请使用初始值设定项:
Foo(size_t size)
: bars(size) {}
当对象被销毁时,bars
及其所有元素也是如此,因此没有机会忘记清理或不正确地进行清理。
如果性能是一个问题,可以将其转换为一种Matrix2D
类,其作用类似于2D数组,但实际上只有一个基础的一维数组。
答案 2 :(得分:0)
#include <iostream>
#include <vector>
using namespace std;
class Bar {
public:
int BarInfo;
};
class Foo {
public:
Foo() {
// Allocates 10 vector spots for 10 bar elements - 100 bars, 10 x 10
for (int i = 0; i < 10; i++) {
// Puts 10 bars pointer at the end;
// Heap-allocated (dynamically), which
// means it survives until you delete it
// The [10] is array syntax, meaning you'll have 10 bars
// for each bars[index] and then
// you can access it by bars[index][0-9]
// If you need it to be more dynamic
// then you should try vector<vector<Bar>>
bars.push_back(new Bar[10]);
}
}
Bar* operator[] (int index) {
return bars[index];
}
~Foo () {
// Cleanup, because you have pointers inside the vector,
// Must be done one at a time for each element
for (int i = 0; i < bars.size(); i++) {
// TODO: how to clean up bars properly?
// Each spot in the vector<> contains 10 bars,
// so you use the array deletion
// and not just regular 'delete'
delete[] bars[i]; // deletes the 10 array elements
}
}
private:
// vector might not be a bad idea.
vector<Bar*> bars;
};
这是我测试编写的代码的主要内容,它就像你认为2D数组应该有效一样:
int main ( int argc, char* argv[] ) {
Foo foo;
// Bar at 1st row, 2nd column ( row index 0, column index 1 )
// Bar& is a reference
Bar& bar12 = foo[0][1];
bar12.BarInfo = 25;
int stuffInsideBar = foo[0][1].BarInfo; // 25
return 0;
}
我希望这有助于让你更接近你正在做的事情。我在这里使用了一种技术,可能会超过一个初学者头,使Foo
类的行为与您认为的2D数组一样。它被称为operator overloading。它是C ++中的一个强大功能,因此一旦掌握了更多基础知识,它可能对您未来的项目或当前项目有用。祝好运!
~~~~~~~~~~~~~~~~~~~~~~~
编辑前的旧答案
~~~~~~~~~~~~~~~~~~~~~~~
看起来你做的间接太多了。虽然另一个人的答案告诉你如何清理你已经设法做的事情,但我认为你可以从改变你正在处理课程的方式中受益。
#include <iostream>
#include <vector>
using namespace std;
class Bar {};
class Foo {
public:
Foo() : bars() {
// bars is no longer a pointer-to-vectors, so you can just
// allocate it in the constructor - see bars() after Foo()
//bars = new vector<Bar>();
for (int i = 0; i < 10; i++) {
// Puts 1 bar pointer at the end;
// Heap-allocated (dynamically), which
// means it survives until you delete it
bars.push_back(new Bar());
}
}
~Foo () {
// Cleanup, because you have pointers inside the vector,
// Must be done one at a time for each element
for (int i = 0; i < 10; i++) {
// TODO: how to clean up bars properly?
// TODOING: One at a time
delete bars[i]; // deletes pointer at i
}
}
private:
// You don't need to ** the vector<>,
// because it's inside the class and
// will survive for as long as the class does
// This vector will also be copied to copies of Foo,
// but the pointers will remain the same at the time
// of copying.
// Keep in mind, if you want to share the vector, than
// making it a std::shared_ptr of a
// vector might not be a bad idea.
vector<Bar*> bars;
};
如果您通过引用将类传递给函数,那么类中的vector<Bar*>
将不会复制自身或删除自身,使其保持在单个堆栈帧之后。
在main
中,这应该正确清理,并且比矢量**更容易跟踪。但是,如果出于某种原因需要vector **,那么home_monkey的答案应该会对你有所帮助。
答案 3 :(得分:-1)
我认为分配存在问题。这条线
new vector <Bar*> * [10]
将为您提供一系列指向vector <Bar*> *
类型的对象的点数
需要为vector <Bar*>
类型分配一些额外的内存。
我已经去了,
Foo()
{
bars = new vector<Bar*>*[10]; // A.
for (int i = 0; i < 10; i++)
{
bars[i] = new vector<Bar*>; // B. Extra memory assigned here.
bars[i]->push_back(new Bar); // C.
}
}
要释放资源,您必须撤消上述
~Foo ()
{
for (int i = 0; i < 10; i++)
{
// I'm assuming that each vector has one element
delete bars[i][0]; // Free C
delete bars[i]; // Free B
}
delete [] bars; // Free A
}
答案 4 :(得分:-2)
我不相信你甚至正确地分配它。要撤消你到目前为止所做的事情,你所要做的就是:
for(int i=0; i < 10; ++i)
while(bars[i]->size > 0)
{
delete *bars[i]->front();
pop_front();
}
delete[] bars;
但是,你需要自己分配每个向量,例如在构造函数中:
for(int i=0; i<10; ++i)
bars[i] = new vector<Bar*>();
这需要您将析构函数更改为:
for(int i=0; i < 10; ++i)
{
while(bars[i]->size > 0)
{
delete *bars[i]->front();
pop_front();
}
delete bars[i];
}
delete[] bars;
关于您的更新,我建议您将条形类型更改为:
vector<Bar*>* bars;
和分配到(不需要进行上面建议的for循环分配):
bars = new vector<Bar*>[10];