У меня есть программа C ++ SDL / OpenGL, которая работает около 20 минут, а затем вылетает в ig11icd64.dll
. Сообщение об ошибке из Visual Studio:
Исключение, выданное по адресу 0x00007FFFC4A163E4 (ig11icd64.dll) в memleak.exe: 0xC0000005: Место записи нарушения прав доступа 0x000001F582020000.
Когда программа работает, я замечаю, что столбец Private (KB)
в Resource Monitor постоянно увеличивается примерно до 39 000. Тем не менее, средство диагностики памяти Visual Studio c показывает прямую линию в 48,7 МБ почти все время.
Моя программа довольно проста.
#include <glad/glad.h>
#include <cstdio>
#include "wrappers/sdl_context.h"
bool process_events(SDL_Window* window) {
SDL_Event sdl_event;
while (SDL_PollEvent(&sdl_event)) {
if (sdl_event.type == SDL_QUIT) {
return true;
}
if (sdl_event.type == SDL_WINDOWEVENT &&
sdl_event.window.event == SDL_WINDOWEVENT_CLOSE &&
sdl_event.window.windowID == SDL_GetWindowID(window)) {
return true;
}
}
return false;
}
int main(int argc, char* argv[]) {
wrappers::SdlContext sdl_context("Memleak!!!!",
/*width=*/100,
/*height=*/100);
if (sdl_context.status_ != 0) {
return -1;
}
if (gladLoadGL() == 0) {
printf("Failed to initialize OpenGL loader!\n");
return -1;
}
bool done = false;
while (!done) {
done = process_events(sdl_context.window_);
int display_w, display_h;
SDL_GetWindowSize(sdl_context.window_, &display_w, &display_h);
glViewport(0, 0, display_w, display_h);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SDL_GL_SwapWindow(sdl_context.window_);
}
return 0;
}
, где wrappers::SdlContext
- простая упаковка RAII.
#pragma once
#include <SDL.h>
namespace wrappers {
int sdl_init(const char* title,
const int width,
const int height,
SDL_Window** window,
SDL_GLContext* gl_context) {
const int result = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
if (result != 0) {
printf("Error: %s\n", SDL_GetError());
return result;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
const SDL_WindowFlags window_flags = (SDL_WindowFlags)(
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
*window = SDL_CreateWindow(title,
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
width,
height,
window_flags);
*gl_context = SDL_GL_CreateContext(*window);
SDL_GL_MakeCurrent(*window, *gl_context);
SDL_GL_SetSwapInterval(1); // Enable vsync
return 0;
}
void sdl_cleanup(SDL_Window** window, SDL_GLContext* gl_context) {
if (*gl_context) {
SDL_GL_DeleteContext(*gl_context);
*gl_context = nullptr;
}
if (*window) {
SDL_DestroyWindow(*window);
*window = nullptr;
}
SDL_Quit();
}
// RAII wrapper for sdl_init and sdl_cleanup
class SdlContext {
public:
// non-copyable
SdlContext(const SdlContext&) = delete;
SdlContext& operator=(const SdlContext&) = delete;
// Calls sdl_init, saving results into window_ and gl_context_
SdlContext(const char* title, const int width, const int height);
// Calls sdl_cleanup with &window_ and &gl_context_
~SdlContext();
int status_ = 0;
SDL_Window* window_ = nullptr;
SDL_GLContext gl_context_ = nullptr;
};
SdlContext::SdlContext(const char* title, const int width, const int height) {
status_ = sdl_init(title, width, height, &window_, &gl_context_);
};
SdlContext::~SdlContext() { sdl_cleanup(&window_, &gl_context_); }
} // namespace wrappers
My SDL vesion info:
#define SDL_MAJOR_VERSION 2
#define SDL_MINOR_VERSION 0
#define SDL_PATCHLEVEL 10
Вот изображение стека вызовов во время cra * sh.