【问题标题】:unable to find where memory leaked无法找到内存泄漏的位置
【发布时间】:2020-08-19 05:56:19
【问题描述】:

您好,我目前正在开发我的第一个面向对象的 c++ 项目,当我使用 valgrind 检查内存泄漏时,它会输出:

32 (24 direct, 8 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==1761165==    at 0x4839E86: operator new(unsigned long) (vg_replace_malloc.c:344)
==1761165==    by 0x403E5C: Game::Game() (game.cpp:3)
==1761165==    by 0x404711: Game::loadGame(std::istream&) (game.cpp:109)
==1761165==    by 0x4024B2: main (main.cpp:29)

所以现在我去game.cpp:3检查发生了什么(在game.cpp:109中,我调用了Game* temp_game=new Game),在第3行我调用了构造函数

Game::Game() : game_entity(new EntityVec) {
}

所以我猜在某个时候,我没有释放 EntityVec。但是在仔细检查了我的代码之后,尤其是 loadGame 函数和我的析构函数:

Game *Game::loadGame(std::istream &in){
  Game* temp_game=new Game;
  temp_game->game_maze=Maze::read(in);
  if (temp_game->game_maze == nullptr) {
      delete temp_game;
      return nullptr;
  }
  char c;int x;int y;
  EntityControllerFactory* ecfac=EntityControllerFactory::getInstance();
  while (in>>c){
    Entity* temp_entity=new Entity;
    temp_entity->setGlyph(std::string(1,c));
    temp_game->addEntity(temp_entity);
    if (in >> c) {
        EntityController* temp_controller = ecfac->createFromChar(c);
        temp_entity->setController(temp_controller);
    }
    else {
        delete temp_game;
        return nullptr;
    }
    if (in >> c) {
        temp_entity->setProperties(std::string(1,c));
    }
    else {
        delete temp_game;
        return nullptr;
    }
    if((in>>x)&&(in>>y)){
        temp_entity->setPosition(Position(x,y));
      }
 else {
        delete temp_game;
        return nullptr;
    }
  }
  return temp_game;
}

Game::~Game(){

  delete game_ui;
  delete game_gameRules;
  delete game_maze;
  //delete[] game_entity;
  for(Entity* p: *game_entity){delete p;}
  //game_entity->clear();

}

如果 loadgame 失败,我找不到忘记释放游戏的地方。(如果 loadgame 成功并返回 temp_game,那么 main 应该通过在最后删除它来处理它)。谁能给我一些建议?太感谢了。

【问题讨论】:

  • 您可以帮自己一个忙,改用像std::unique_ptr 这样的智能指针,而不是修补内存泄漏错误。您的内存泄漏错误基本上会消失,您不必担心未来的错误。
  • 请注意,如果您开始关注哪个函数可以抛出以及在哪里抛出,那么您当前的方法将完全爆炸。例如,如果in >> csetProperties 抛出异常会发生什么?您应该阅读RAII,这是现代 C++ 编程的基本技术之一。
  • loadGame()成功后是否删除?你返回一个new'ed 对象,所以你的调用者必须确保清理它。 Best practice 是使用 std::unique_ptr 或类似的方法让 RAII 处理所有资源取消/分配。那么你就不需要任何明确的deletes 并且你的内存泄漏实际上会消失,因为它总是很清楚 正在清理以及 何时 并且因为你不能忘记这样做。
  • 问了我的教授后,我想我在这个项目中是不允许使用智能指针的,虽然用起来真的很方便。此外,我们的指南告诉我们给定的测试都是有效的,所以我不必担心异常
  • @AdrianMole 谢谢!我以为我必须做类似 game_entity.erase();现在我的代码没有泄漏,谢谢!

标签: c++ memory-leaks destructor delete-operator


【解决方案1】:

每个new 都应该有一个对应的delete。在您的 Game 构造函数中,您使用 new 创建 game_entity - 但析构函数不会删除它(仅删除它的“成员”)。

您需要一个delete game_entity; 析构函数中的for 循环。

【讨论】:

    猜你喜欢
    • 2014-08-26
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    • 1970-01-01
    • 2018-04-07
    相关资源
    最近更新 更多