在没有显式命令的情况下在函数调用之间清除数组指针数据?

Mak*_*gan 26 c++ pointers memory-management

我有以下问题:

在C++程序中,我有一个声明为的全局数据结构Renderer Rendering_Handler,其中包含一个定义为的成员字段vector<Render_Info> visble objects.

数据结构本身正在做什么并不重要,它们是抽象数据以并行化我的程序所需的包装器.

要清楚,Rendering_Handler是完全全局的,它实际上是一个单例(我可以100%确认构造函数已被调用一次,对于此类只调用一次).

我已经声明了以下类方法:

Render_Info* Renderer::add_Render_Info()
{
    visible_objects.push_back(Render_Info());
    return &(visible_objects.back());
}
Run Code Online (Sandbox Code Playgroud)

很简单,它创建一个新Render_Info结构,将它附加到visible_objects数组并返回指向该对象的指针.

调用的另一个数据结构Chunk具有定义为的构造函数

Chunk::Chunk(vec3 offset, World* w) 
{
    /*initialize some values*/

    draw_info = Rendering_Handler->add_Render_Info();
    draw_info->VBOs = vector<GLuint>(5);

    /*initialize OpenGL VAOs, VBOs and other buffer objects*/

    cout << draw_info->VBOs.size() << endl;
    cout << draw_info << endl;
}
Run Code Online (Sandbox Code Playgroud)

它还有一个定义为的方法:

void Chunk::update_render_info()
{
    cout << draw_info->VBOs.size() << endl;
    cout << draw_info << endl;

    /*OpenGL stuff*/

}
Run Code Online (Sandbox Code Playgroud)

最后

我们有初始化所有内容的方法:

World::World()
{   
    /*Initialize chunks in a circular 3D array*/
    loaded_chunks = new Chunk_Holder(h_radius, h_radius, v_radius, this);

    for(int i=0; i<h_radius; i++)
    {
        for(int j=0; j<h_radius; j++)
        {
            for(int k=0; k<v_radius; k++)
            {
               (*loaded_chunks)(i,j,k)->update();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

rpgram的输出是:

在此输入图像描述

...

在此输入图像描述

让我们关注输出的第2行和最后2行,它们对应于我为调试添加的打印语句.

前两行表示在位置0x556edb7ae200处已将5个元素添加到缓冲区

最后两行告诉我相同的缓冲区(因为内存位置相同)现在包含0个元素.

从代码的快照中可以看出,在创建Chunks和更新它们之间没有调用任何函数.有没有人知道可能导致这些元素消失的原因是什么?

我没有正确保留记忆吗?由于错误分配,这些对象是否在我不知情的情况下被清除?

haa*_*awk 9

我认为问题在于你在向量中存储指向元素的指针,同时你不断调用vector::push_back哪个,然后必须调整向量的大小并将所有元素移动到新的内存块.这将使之前获得的所有指针无效.

为您提供更多上下文:vector将其元素存储在连续的内存块中.当vector::push_back被调用并且在这块内存中没有剩余空间时,那么vector将分配另一块大小为旧块大小两倍的内存块.然后它将所有元素从旧块复制/移动到新块.最后,旧的大块将被摧毁.当你打电话时,&(visible_objects.back())你将获得一个内存中的地址,该地址是当前内存块所拥有的visible_objects.如果稍后visible_objects.push_back被调用并且visible_objects必须迁移到新的更大的内存块,则之前获得的所有地址将是陈旧的,因为它们指向已经被破坏的旧的内存块.