尝试对私有变量使用 getter 时发生访问冲突?

问题描述 投票:0回答:1

我正在尝试使用类的私有变量来制作SDL窗口。为了从私有变量创建一个窗口,我尝试使用 getter 和 setter。但是,我收到此错误:

ShootemUp.exe 中的 0x00007FFBF93852D7 (SDL2.dll) 处抛出异常:0xC0000005:读取位置 0x0000000100000008 时发生访问冲突。

我该如何解决这个问题?

这是我的代码:

#include "common.h"

void Init() {
    int windowFlag, rendererFlag;
    rendererFlag = SDL_RENDERER_ACCELERATED;
    windowFlag = 0;

    App application;

    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        std::cout << "Couldn't intialize SDL! Error:" << SDL_GetError;
        exit(-1);
    }
    else {

        SDL_Window* window = NULL;
        window = SDL_CreateWindow("Shoot em' up", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
        application.setWindow(window);
        SDL_DestroyWindow(window);
        if (!application.getWindow()) {
            std::cout << "Window not intialized! Error:" << SDL_GetError;
            exit(-1);
        }

        SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
        
        SDL_Renderer* renderer = NULL;
        renderer = SDL_CreateRenderer(application.getWindow(), -1, rendererFlag);
        application.setRenderer(renderer);
        if (!application.getRenderer()) {
            std::cout << "Renderer not intialized! Error:" << SDL_Error;
            exit(-1);
        }
    }
}

我在这一行收到错误:

renderer = SDL_CreateRenderer(application.getWindow(), -1, rendererFlag);

我尝试使用私有窗口变量创建渲染器。

这是带有 getter 和 setter 的文件:

#include "Common.h"

void App::setWindow(SDL_Window* window) {
    this->window = window;
}

void App::setRenderer(SDL_Renderer* renderer) {
    this->renderer = renderer;
}

SDL_Window* App::getWindow() {
    return window;
}

SDL_Renderer* App::getRenderer() {
    return renderer;
}
c++ sdl access-violation
1个回答
1
投票

您在将

SDL_Window
对象交给您的
application
对象后将其销毁,从而留下一个 悬空指针,然后
App::getWindow()
随后返回:

SDL_Window* window = NULL;
window = SDL_CreateWindow(...);
application.setWindow(window); // <-- sets App::window, OK here
SDL_DestroyWindow(window); // <-- now App::window is dangling!
...
renderer = SDL_CreateRenderer(application.getWindow(), ...); // <-- AV using invalid App::window!

当您将

SDL_Window
对象传递给
SDL_CreateRenderer()
时,它就不再有效,这就是 AV 发生的原因。

您的

if (!application.getWindow())
检查无法检测到这种情况,因为存储在
SDL_Window*
对象内的
application
指针不是
nullptr
,它仍然指向您销毁的内存。为了避免这种情况,您必须在拨打
application.setWindow(nullptr)
之后再拨打
SDL_DestroyWindow()

因此,真正的解决方法是在某些东西仍在使用

SDL_Window
对象时不要销毁它! 对
SDL_DestroyWindow()
(和
SDL_DestroyRenderer()
,此代码中缺少)的调用需要稍后在代码中完成,在
application
对象使用
SDL_Window
(和
SDL_Renderer
)完成之后,例如在
App::~App()
析构函数中(或者至少在
application
对象被销毁之后)。

© www.soinside.com 2019 - 2024. All rights reserved.