I seem to be getting a memory leak in my SDL/OpenGL program on MacOS. I’ve tracked it down to the SDL_GL_SwapWindow call that I do every frame – looks like it’s allocating 104 bytes every single frame.
Here’s a screenshot from Instruments, which I’m using to tell where the memory leak is coming from:
As you can see, the stack trace comes from main
, specifically the call to Cocoa_GL_SwapWindow
. Then if you look at the table showing all the allocations, you can see by the timestamp that they are coming multiple times per millisecond, so it’s happening every frame.
SDL is big enough and I inexperienced enough that it seems pretty unlikely this is a problem with SDL2 and not with my own code … So what am I doing wrong??
Here’s the code where I can repro the problem:
#include <cstdio>
#include "SDL.h"
// openGL includes
#define GL_SILENCE_DEPRECATION // otherwise we get a ton of "opengl deprecated" warnings
#include "OpenGL/gl.h"
#define glGenVertexArrays glGenVertexArraysAPPLE
#define glBindVertexArray glBindVertexArrayAPPLE
#define glDeleteVertexArrays glDeleteVertexArraysAPPLE
SDL_Window *window = nullptr;
SDL_GLContext glContext = nullptr;
bool shouldQuit = false;
int main(int argc, char* argv[]) {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
// not sure this is necessary
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow(
"SDL2 Test",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
640,
480,
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL
);
if (window == nullptr) {
printf("error creating window: %s", SDL_GetError());
SDL_Quit();
return 1;
}
glContext = SDL_GL_CreateContext(window);
if (glContext == nullptr) {
printf("error creating SDL_GLContext: %s", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
SDL_GL_MakeCurrent(window, glContext);
SDL_GL_SetSwapInterval(1); // enable vsync
while (!shouldQuit) {
//update
SDL_Event e;
while (SDL_PollEvent(&e)) {
switch (e.type) {
case SDL_QUIT:
shouldQuit = true;
break;
case SDL_KEYDOWN:
if (e.key.keysym.sym == SDLK_ESCAPE) {
shouldQuit = true;
}
break;
}
}
// draw
glClearColor(1.0f, 0, 0, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SDL_GL_SwapWindow(window);
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
I’ve also put it up on GitHub if you want to take a look at the build script I’m using (CMake).