[英]Class creating multiple objects of another class at the same memory location (C++)
[英]C++ initializer constantly creating new objects at same memory location
我有一个简单的递归类型的容器对象“ Level”(例如目录,它可以包含其自身的倍数),尽管我不确定这与该问题有关。
//Level.h
class Level
{
public:
Level();
vector<Level*> SubLevels;
Level CreateSubLevel();
}
//Level.cpp
Level::Level()
{
SubLevels = vector<Level*>();
}
Level Level::CreateSubLevel()
{
Level NewLevel = Level();
SubLevels.push_back(&NewLevel);
return NewLevel;
}
如果然后在我的主循环中
//main.cpp
Level MasterLevel = Level();
MasterLevel.CreateSubLevel();
MasterLevel.CreateSubLevel();
MasterLevel.CreateSubLevel();
我发现确实矢量MasterLevel.SubLevels包含三个指向Level对象的指针。 但是,它们都是指向相同地址的指针!
我不确定为什么会这样。 我缺少内存管理技能-但是我怀疑是因为每次调用CreateSubLevel()时都会创建一个新对象,但是当CreateSubLevel()退出时会删除该对象吗? 我以为ARC会跟踪指向它的指针仍然存在的事实,但是也许我弄错了? 还是完全是另一个问题?
我怎样才能最好地解决这个问题?
谢谢!
SubLevels
拥有三个指向临时对象的指针。 编译器每次选择为临时使用相同的内存并不奇怪-为什么不呢?
如果要实际正确存储三个不同的Level
,则必须按值存储它们:
vector<Level> SubLevels;
SubLevels.push_back(Level());
或实际分配Level
:
vector<Level*> SubLevels;
SubLevels.push_back(new Level); // don't forget to delete!
每次使用相同值的原因是因为您正在使用临时变量的地址(在堆栈上)。 每次调用函数CreateSubLevel()
,堆栈都会被重用,因此对象每次调用都存储在相同的位置。
您可以使用operator new()
在堆上分配对象:
vector<Level*> SubLevels;
SubLevels.push_back(new Level);
然后,您可以在析构函数中将其delete
:
Level::~Level()
{
vector<Level*>::iterator i;
for (i = SubLevels.begin(); i != SubLevels.end(); ++i)
delete *i;
}
您有三个对MasterLevel.CreateSubLevel();
调用MasterLevel.CreateSubLevel();
一个接一个地。 每次调用都会创建一个大小相同的堆栈帧。 因此,局部变量的地址是相同的。 您正在将局部变量的地址存储在SubLevels
。
如果使用存储在SubLevels
的地址,则会遇到未定义的行为。 您需要从堆分配内存。
在使用它时,请保留智能指针列表std::unique_ptr
或std::shared_ptr
而不是存储原始指针。
采用
vector<std::shared_ptr<Level>> SubLevels;
并将其用作:
void Level::CreateSubLevel()
{
SubLevels.push_back(std::make_shared<Level>());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.