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

问题描述 投票:26回答:1

我有以下问题:

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

很简单,它创建一个新的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;
}

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

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

    /*OpenGL stuff*/

}

最后

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

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

该计划的输出是:

enter image description here

...

enter image description here

让我们关注输出的前2行和后2行,它们对应于我为调试添加的print语句。

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

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

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

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

c++ pointers memory-management
1个回答
9
投票

我认为问题在于你在向量中存储指向元素的指针,同时你不断调用vector::push_back,它不时地调整向量并将所有元素移动到新的内存块。这将使之前获得的所有指针无效。

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

© www.soinside.com 2019 - 2024. All rights reserved.