Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;初始值设定项在同一内存位置不断创建新对象_C++_Pointers_Automatic Ref Counting - Fatal编程技术网

C++ C++;初始值设定项在同一内存位置不断创建新对象

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”(比如一个目录,它可以包含自身的倍数),尽管我不确定这是否与这个问题有关

//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>());
}