指针内存泄漏的可能性?

时间:2018-01-04 20:48:02

标签: c++ class pointers memory-leaks

我有一个用c ++编写的基本Game类,以及一个Character类,它将指向游戏的指针作为其构造函数的参数。我对所有这些新奇的“C ++”和“指针”爵士乐都很陌生,所以如果这看起来像是一个无聊的问题,请耐心等待。实际代码还有更多功能,但出于演示目的,我将其压缩了一点:

class Game {
  Game() { /* blah blah blah */ };
  ~Game() {};
};
class Character {
  Character(Game *game, unsigned int x, unsigned int y) {
    /* here there be dragons */
  };
  ~Character() {} // empty destructor
};

我的问题是,在完成任何给定的角色后,是否需要删除指向主游戏实例的指针,或者指针完全与内存泄漏无关?在任何给定的时间点,我在一个游戏中有800多个字符,所以如果指针导致内存泄漏,则会出现一些问题。

2 个答案:

答案 0 :(得分:1)

  

我的问题是,在完成任何给定角色后,是否需要删除指向主游戏实例的指针

不一定。

应该销毁指向的Game实例,并确保所有对象都可以,但是Character实例应该对此负责吗?

你说会有很多字符实例。考虑一下:还会有很多游戏实例吗?每个角色都指向自己的游戏对象吗?

如果每个角色都有自己独立的游戏,那么角色确实有责任破坏他们的游戏。在这种情况下,使用指针可能会有意义,因为使用直接子对象会更简单。

但是如果很多角色都指的是共享游戏(我怀疑是这种情况),那么单个角色就不能拥有该游戏的唯一所有权,因为只要任何一个角色被摧毁,其他角色就会被破坏。还是指着那场比赛。

以下是共享所有权的两种方法

  1. 使用寿命比任何字符实例更长的游戏实例。例如,main函数中的静态对象或自动对象。这样,没有人物负责破坏。棘手的部分是确保在游戏开始前销毁所有角色实例。

  2. 使用引用计数智能指针,例如std::shared_ptr。这样,当最后一个角色出现时,游戏就会被破坏。

答案 1 :(得分:1)

由于您动态初始化Game对象,因此在您明确执行此操作之前不会销毁它。所以是的,在某个时间点,如果您使用指针和动态分配,则需要销毁Game对象。

您可以通过以下方式测试:

#include <iostream>
class Game {
public:
    Game() 
    {
        std::cout << "Game Object Initialized\n";
    }
    ~Game()
    {
        std::cout << "Game object destroyed\n";
    }
};
class Character {
    Game *g;
public:
    Character(Game *game, unsigned int x, unsigned int y) {
        g = game;
        std::cout << "Character Object Initialized\n";
    }
    ~Character()
    {
        std::cout << "Character Object Destroyed\n";
    }
};

void main()
{
    Game *gameObj = new Game();
    Character *characterObj = new Character(gameObj, 0, 0);
    delete characterObj;

}
  

输出:

     

游戏对象已初始化

     

字符对象已初始化

     

字符对象被破坏

在这种情况下,gameObjcharacterObj被销毁后仍然可以访问。您可以将此对象传递给新角色。当然,需要使用delete gameObj;销毁它。

如果您希望在释放所有字符时自动销毁Game对象:正如其他人提到的那样,您可以使用shared_ptr对象。

#include <iostream>
#include <memory>

class Game {
public:
    Game()
    {
        std::cout << "Game Object Initialized\n";
    }
    ~Game()
    {
        std::cout << "Game object destroyed\n";
    }
};
class Character {
    std::shared_ptr<Game> g;
public:
    Character(std::shared_ptr<Game> game, unsigned int x, unsigned int y)
    {
        g = game;
        std::cout << "Character Object Initialized\n";
    }
    ~Character()
    {
        std::cout << "Character Object Destroyed\n";
    }
};

void main()
{
    //to instantiate a shared_ptr, pass pointer to game as argument in constructor
    std::shared_ptr<Game> gameObj(new Game()); 
    Character *characterObj_0 = new Character(gameObj, 0, 0);
    Character *characterObj_1 = new Character(gameObj, 0, 0);

    delete characterObj_0;
    delete characterObj_1;

    Character *characterObj_2 = new Character(gameObj, 0, 0);

    delete characterObj_2;
}
  

游戏对象已初始化

     

字符对象已初始化

     

字符对象已初始化

     

字符对象被破坏

     

字符对象被破坏

     

字符对象已初始化

     

字符对象被破坏

     

游戏对象被破坏