2017-04-22 57 views
0

,所以我有一個單獨的遊戲類,像這樣:辛格爾頓導致內存泄漏

class GameScene 
{ 
public: 
    ~GameScene(); 

    static GameScene& GetInstance() 
    { 
     static GameScene instance; 
     return instance; 
    }; 

    void MainMenu(); 
    void Gameplay(); 
    void GameOver(); 

    Sprite Sprites; 
    Text* aText[2]; 
private: 
    string MenuText[4]; 
    TextLabel* m_pText[5]; 

    GameScene(); 
    GameScene(const GameScene&) {} 
    GameScene& operator=(const GameScene&) {}; 
}; 

請注意,我用的單身不是專家,這是我使用這種特殊的設計模式是第一次。

上面這個類的目的是爲了避免在main.cpp中實例化多個遊戲對象,並且只使用一個可引用所有這些不同對象的單例實例。這是我如何定義的類:

#include "GameScene.h" 

GameScene::GameScene() 
{ 
    m_pText[0] = new TextLabel("arial.ttf"); 
    m_pText[1] = new TextLabel("arial.ttf"); 
    m_pText[2] = new TextLabel("arial.ttf"); 
    m_pText[3] = new TextLabel("arial.ttf"); 

    // Do stuff with MenuText etc... 
} 

GameScene::~GameScene() 
{ 
    // This is not being called :( 
    for (int i = 0; i < 4; ++i) 
    { 
     delete m_pText[i]; 
     m_pText[i] = nullptr; 
    } 
} 

void GameScene::MainMenu() 
{ 
    // Display some texts... 
} 

void GameScene::Gameplay() 
{ 
    // Display some texts... 
} 

void GameScene::GameOver() 
{ 
    // Display some texts... 
} 

最後,不知道如何相關,這是,這個問題可能已經顯得明顯一些你,但這裏是在main.cpp中用法的例子:

{295} normal block at 0x08A668F0, 44 bytes long. 
Data: < pn   > F0 E4 86 04 70 6E A6 08 F0 E4 86 04 01 00 CD CD 
{294} normal block at 0x08A66DC0, 44 bytes long. 
Data: <Pu 8r l  > 50 75 A6 08 38 72 A6 08 08 6C A6 08 00 00 CD CD 
{293} normal block at 0x08A66840, 44 bytes long. 

注:

// Global Objects 
GameScene* Manager; 

// ... 
// In a start up function() 
Manager->GetInstance().aText[0] = new TextLabel("arial.ttf"); 
    Manager->GetInstance().aText[0]->Scale(0.2f); 
    Manager->GetInstance().aText[0]->Color(glm::vec3(1.0f, 1.0f, 0.0f)); 
// ... 

// Finally in the render() function 
// ... 
if (IsPlaying) 
    { 
     GameManager->GetInstance().Sprites.Render(); 
     GameManager->GetInstance().aText[0]->Render(); 
     // ... 
    } 

內存泄漏我有實例,我知道,我應該重新分配「aText」在某些時候,但問題是,不只是從aText陣列內存泄漏。我得到了數百次內存泄漏(儘管我甚至沒有分配那麼多的內存),它肯定與靜態實例有關。任何簡單的方法來解決這個問題?謝謝。

+1

使用'unique_ptr' +溝渠那個管理員,直接調用這個單例'GameScene :: GetInstance()' –

+0

你是否在析構函數中放置了一個斷點? – Ronnie

回答

0

當你第一次叫GameScene::GetInstance你的靜態實例構造,但

析構函數(12.4),靜態存儲持續時間 (在塊範圍內或在命名空間內聲明的)的初始化的對象被稱爲結果 從主要返回和由於退出(18.3)。

因此,即使沒有內存泄漏檢查代碼,也可能會報告內存泄漏。只有析構函數尚未被調用。

示例代碼missreports內存泄漏:

#include <memory> 

#define _CRTDBG_MAP_ALLOC 
#include <crtdbg.h> 

class A { 
public: 
    A() : pi(std::make_unique<int>(0)) {} 
    std::unique_ptr<int> pi; 
    static void CreateInstance() { 
     static A instanceFunction; 
    } 
}; 

void main() { 
    _CrtMemState initialMemoryState; 
    _CrtMemCheckpoint(&initialMemoryState); 

    A::CreateInstance(); 

    _CrtMemState finalMemoryState; 
    _CrtMemCheckpoint(&finalMemoryState); 
    _CrtMemState differenceMemoryState; 
    if (_CrtMemDifference(&differenceMemoryState, &initialMemoryState, &finalMemoryState)) 
     _CrtMemDumpAllObjectsSince(&initialMemoryState); 
} 

爲了解決這個問題,你可以定義靜態實例作爲一類memeber不是一個局部變量。

頭文件:

#pragma once 
#include <memory> 

class A { 
public: 
    A() : pi(std::make_unique<int>(0)) {} 
    std::unique_ptr<int> pi; 
    static A& GetInstance() { 
     return instance_; 
    } 
private: 
    static A instance_; 
}; 

cpp文件:

#include "A.h" 

A A::instance_; 

另一種解決方案是使用Init/Shutdown對。

+0

Scott Meyer的單身人士呢? –