C++ C++;初始值设定项在同一内存位置不断创建新对象
我有一个简单的递归类型容器对象“Level”(比如一个目录,它可以包含自身的倍数),尽管我不确定这是否与这个问题有关C++ C++;初始值设定项在同一内存位置不断创建新对象,c++,pointers,automatic-ref-counting,C++,Pointers,Automatic Ref Counting,我有一个简单的递归类型容器对象“Level”(比如一个目录,它可以包含自身的倍数),尽管我不确定这是否与这个问题有关 //Level.h class Level { public: Level(); vector<Level*> SubLevels; Level CreateSubLevel(); } //Level.cpp Level::Level() { SubLevels = vector<Level*>(); } 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;
}
我发现向量MasterLevel.SubLevels确实包含三个指向Level对象的指针。然而,它们都是指向同一地址的指针
我不知道为什么会这样。我的内存管理技能不足——但我怀疑这是因为每次调用CreateSubLevel()时,都会创建一个新对象,但当CreateSubLevel()退出时,它会被删除?我以为ARC会跟踪指向它的指针仍然存在的事实,但也许我错了?还是完全是另一个问题
我怎样才能最好地解决这个问题
谢谢
子级别
持有三个指向临时级别的指针。编译器每次都选择将相同的内存用于临时内存,这并不奇怪——为什么不呢
如果要正确存储三个不同的级别
s,则必须按值存储它们:
vector<Level> SubLevels;
SubLevels.push_back(Level());
subvels
持有三个指向临时人员的指针。编译器每次都选择将相同的内存用于临时内存,这并不奇怪——为什么不呢
如果要正确存储三个不同的级别
s,则必须按值存储它们:
vector<Level> SubLevels;
SubLevels.push_back(Level());
每次使用相同值的原因是使用临时变量(在堆栈上)的地址。每次调用函数
CreateSubLevel()
时,堆栈都会被重用,因此每次调用时对象都存储在相同的位置
您可以使用操作符new()
在堆上分配对象:
每次使用相同值的原因是使用临时变量(在堆栈上)的地址。每次调用函数
CreateSubLevel()
时,堆栈都会被重用,因此每次调用时对象都存储在相同的位置
您可以使用操作符new()
在堆上分配对象:
您有三个对
MasterLevel.CreateSubLevel()的调用代码>一个接一个。每个调用都会创建一个大小相同的堆栈帧。因此,局部变量的地址是相同的。您正在将局部变量的地址存储在子级别中
如果您使用存储在子级别中的地址
,您将遇到未定义的行为。您需要从堆中分配内存
在使用时,保留一个智能指针列表,std::unique_ptr
或std::shared_ptr
,而不是存储原始指针
使用
向量子级;
并将其用作:
void Level::CreateSubLevel()
{
SubLevels.push_back(std::make_shared<Level>());
}
void级别::CreateSubLevel()
{
子级。推回(std::make_shared());
}
您有三个对MasterLevel.CreateSubLevel()的调用代码>一个接一个。每个调用都会创建一个大小相同的堆栈帧。因此,局部变量的地址是相同的。您正在将局部变量的地址存储在子级别中
如果您使用存储在子级别中的地址
,您将遇到未定义的行为。您需要从堆中分配内存
在使用时,保留一个智能指针列表,std::unique_ptr
或std::shared_ptr
,而不是存储原始指针
使用
向量子级;
并将其用作:
void Level::CreateSubLevel()
{
SubLevels.push_back(std::make_shared<Level>());
}
void级别::CreateSubLevel()
{
子级。推回(std::make_shared());
}
您正在推送临时对象的地址NewLevel
返回时不再存在,它被复制到一个新实例,但您刚才推后的地址无效。嗯,好吧,我想可能是这样的。那么,有没有一个理想的解决方案呢?将向量更改为存储对象而不是指针可以解决问题吗?@StuartBarth是的,使用值而不是指针可能更可取。您正在推送临时对象的地址NewLevel
返回时不再存在,它被复制到一个新实例,但您刚才推后的地址无效。嗯,好吧,我想可能是这样的。那么,有没有一个理想的解决方案呢?将向量更改为存储对象而不是指针可以解决问题吗?@StuartBarth是的,使用值而不是指针可能更可取。好的,谢谢。我想我还有一些关于分配的知识要学!好的,谢谢。我想我还有一些关于分配的知识要学!
Level::~Level()
{
vector<Level*>::iterator i;
for (i = SubLevels.begin(); i != SubLevels.end(); ++i)
delete *i;
}
vector<std::shared_ptr<Level>> SubLevels;
void Level::CreateSubLevel()
{
SubLevels.push_back(std::make_shared<Level>());
}