【问题标题】:Freeing memory in std::vector释放 std::vector 中的内存
【发布时间】:2017-05-12 03:44:11
【问题描述】:

我有一个名为 GameState 的抽象类,看起来像这样,

#ifndef GAMESTATE_H
#define GAMESTATE_H

#include <iostream>

class GameState
{
public:
    virtual ~GameState(void) = 0 { std::cout << "~GameState" << std::endl; };

    virtual void init     (void) = 0;
    virtual void update   (void) = 0;
    virtual void shutdown (void) = 0;

private:

};

#endif

在main.cpp中,

// Lv1Stage and Lv2Stage is derived class from GameState class.
GameState* lv1Stage = new Lv1Stage
GameState* lv2Stage = new Lv2Stage

// This adds states to state vector which is in gameStateManager.
gameStateManager.addState(lv1Stage);
gameStateManager.addState(lv2Stage);



while(gameStateManager.getType() != ST_QUIT)
    {
        gameStateManager.update();
    }

当我退出游戏时(当我退出循环时),我必须释放分配给 GameState 的记忆。所以我在 GameStateManager 中做了一个函数,叫做 clean,看起来像这样。

void GameStateManager::clean(void)
{   
    while (!_states.empty())
    {
         //first, release all memories of each states.
        _states.back()->shutdown();
         //and then, clear memory of state..
        _states.pop_back();
    }

    _states.clear();

}

我制作这个干净的功能的原因是,我不想删除我每次添加的所有游戏状态,比如,

delete lv1Stage;
delete lv2Stage;
delete lv3Stage;
... 

所以我将 clean() 函数放入了 gameStateManager 的析构函数中,但由于我检测到内存泄漏,它似乎不起作用。

但问题是,当我像上面的代码一样自己删除所有状态时,没有检测到内存泄漏。但是,它会导致未处理的异常(我的猜测是因为 _states 为空,因为我手动删除了它)。

所以,总而言之, - 我使用 clean 函数在析构函数中取消分配向量组件(即游戏状态)的内存。

  • 但它似乎不起作用(内存泄漏)

  • 但是,我自己删除所有记忆让我很困扰。

你们能给我一些解决方案吗?或者,我错过了什么?

【问题讨论】:

  • GameState* lv1Stage = new Lv1Stage GameState* lv2Stage = new Lv2Stage 不是有效的 C++。如果_states 是std::vector&lt;GameState*&gt;,那么您还需要delete _states.back();。考虑改用std::vector&lt;std::unique_ptr&lt;GameState&gt;&gt;,并让~GameState() 隐式销毁自己的资源。然后,您只需拨打_states.clear(); 即可释放所有资源。
  • See this example。请注意,对states.clear() 的调用是多余的,因为向量及其内容在超出范围时会自动销毁。这里要注意的重要一点是,std::unique_ptr 在销毁时会自动为您提供delete 的内容(在这种情况下通过states.clear();)。
  • _states 是指针向量吗?如果是这样,你永远不会删除那些指针
  • 因为这显然是一个初学者问题:需要调用delete 与vector 无关。 vector 管理自己的内存。对delete的需求来自new的使用。

标签: c++ memory vector memory-management memory-leaks


【解决方案1】:

您的vector 持有GameState* 指向使用new 分配的对象的指针。他们必须通过delete 释放。因此,您需要添加它,例如:

_states.back()->shutdown();
delete _states.back(); // <-- add this!
_states.pop_back();

如果您使用的是 C++11 或更高版本,您可以将 vector 更改为保存 std::unique_ptr&lt;GameState&gt; 对象而不是原始的 GameState* 指针,然后当您删除对象时将自动为您调用 delete来自向量。

【讨论】:

    猜你喜欢
    • 2023-03-22
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 2011-08-30
    相关资源
    最近更新 更多