(Проблема рендеринга SDL) C ++ Исключение: нарушение прав чтения. ЭТО было nullptr - PullRequest
0 голосов
/ 19 апреля 2019

Всякий раз, когда я запускаю свою программу, я получаю исключение в двух отдельных строках кода, если я закомментирую одну из них, проблема переходит к другой, но обе ссылаются на одну и ту же переменную.

GameScreenManager.cpp:

#pragma once
#include <SDL.h>
#include "Commons.h"
#include "GameScreenManager.h"
#include "GameScreenLevel1.h"
#include "GameScreen.h"

GameScreenManager::GameScreenManager(SDL_Renderer* renderer, SCREENS startScreen)
{
    SDL_Renderer* mRenderer;
    mRenderer = NULL;
    ChangeScreen(startScreen);
}

GameScreenManager::~GameScreenManager()
{
    mRenderer = NULL;
    delete mCurrentScreen;
    mCurrentScreen = NULL;
}

void GameScreenManager::Render()
{
    mCurrentScreen->Render();
}

void GameScreenManager::update(float deltaTime, SDL_Event e)
{
    mCurrentScreen->Update(deltaTime, e);
}

void GameScreenManager::ChangeScreen(SCREENS newScreen)
{
    //Clear up the old screen
    if (mCurrentScreen != NULL)
    {
        delete mCurrentScreen;
    }

    GameScreenLevel1* tempScreen;


    switch (newScreen)
    {
    case SCREEN_INTRO:
        break;
    case SCREEN_MENU:
        break;
    case SCREEN_LEVEL1:
        tempScreen = new GameScreenLevel1(mRenderer);
        mCurrentScreen = (GameScreen*)tempScreen;
        tempScreen = NULL;
        break;
    case SCREEN_LEVEL2:
        break;
    case SCREEN_GAMEOVER:
        break;
    case SCREEN_HIGHSCORES:
        break;
    default:
            break;
    }
}

GameScreenManager.h:

#pragma once
#ifndef _GAMESCREENMANAGER_H
#define _GAMESCREENMANAGER_H
#include <SDL.h>
#include "Commons.h"

class GameScreen;

class GameScreenManager
{
    private:
        SDL_Renderer*    mRenderer;
        GameScreen*      mCurrentScreen;

    public:
        GameScreenManager(SDL_Renderer* renderer, SCREENS startScreen);
        ~GameScreenManager();

        void Render();
        void update(float deltaTime, SDL_Event e);
        void ChangeScreen(SCREENS newScreen);
};

#endif //_GAMESCREENMANAGER_H

В настоящее время проблема возникает в строке 24;

    mCurrentScreen->Render();

Однако, если я закомментирую эту строку, она появится в строке29:

    mCurrentScreen->Update(deltaTime, e);

"Создано необработанное исключение: нарушение прав чтения. this was nullptr. Произошло"

Ответы [ 2 ]

0 голосов
/ 20 апреля 2019

Так получилось, что я на самом деле пропустил строку кода, которая задала mCurrentScreen, и оператор switch не проходил корректно, поэтому он не срабатывал. Кроме того, переменная mRenderer не была правильно настроена ни в одном из моих файлов cpp, поскольку каждый раз, когда я пытался ее использовать, возвращался «Недопустимый рендер». Ниже приведен рабочий код, спасибо за помощь всем, он направил меня в правильном направлении;

#pragma once
#include <SDL.h>
#include "Commons.h"
#include "GameScreenManager.h"
#include "GameScreenLevel1.h"
#include "GameScreen.h"

GameScreenManager::GameScreenManager(SDL_Renderer* renderer, SCREENS startScreen)
{
    mRenderer = renderer;
    GameScreen* mCurrentScreen = NULL;
    ChangeScreen(startScreen);
}

GameScreenManager::~GameScreenManager()
{
    mRenderer = NULL;
    delete mCurrentScreen;
    mCurrentScreen = NULL;
}

void GameScreenManager::Render()
{
    mCurrentScreen->Render();
}

void GameScreenManager::Update(float deltaTime, SDL_Event e)
{
    mCurrentScreen->Update(deltaTime, e);
}

void GameScreenManager::ChangeScreen(SCREENS newScreen)
{
    //Clear up the old screen
    if (mCurrentScreen != NULL)
    {
        delete mCurrentScreen;
    }

    GameScreenLevel1* tempScreen;

    switch (newScreen)
    {
    case SCREEN_INTRO:
        break;
    case SCREEN_MENU:
        break;
    case SCREEN_LEVEL1:
        tempScreen = new GameScreenLevel1(mRenderer);
        mCurrentScreen = (GameScreen*)tempScreen;
        tempScreen = NULL;
        break;
    case SCREEN_LEVEL2:
        break;
    case SCREEN_GAMEOVER:
        break;
    case SCREEN_HIGHSCORES:
        break;
    default:
        break;
    }
}
0 голосов
/ 19 апреля 2019

Очевидно, что поле mCurrentScreen равно NULL, когда вы вызываете Render () или update (). Либо защитите звонки, проверив mCurrentScreen на NULL:

void GameScreenManager::Render()
{
    if (mCurrentScreen != NULL)
        mCurrentScreen->Render();
}

void GameScreenManager::update(float deltaTime, SDL_Event e)
{
    if (mCurrentScreen != NULL)
        mCurrentScreen->Update(deltaTime, e);
}

или убедитесь, что mCurrentScreen установлен перед вызовом Render () или Update ().

...