I've been creating a 2D game in sdl2 in C and within my main game loop, I have found a section of code that causes a massive memory leak in my program, roughly leaking 100MB of memory per second.
The relevant code is below:
renderTexture(textBox(buffer[0], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, 20, 240, NULL);
renderTexture(textBox(buffer[1], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, 287,240, NULL);
renderTexture(textBox(buffer[2], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, 554,240, NULL);
renderTexture(textBox(buffer[3], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, 821,240, NULL);
renderTexture(textBox(buffer[4], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, 20,450, NULL);
renderTexture(textBox(buffer[5], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, 287,450, NULL);
renderTexture(textBox(buffer[6], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, 554,450, NULL);
renderTexture(textBox(buffer[7], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, 821,450, NULL);
renderTexture(textBox(buffer[8], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, 20,660, NULL);
renderTexture(textBox(buffer[9], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, 287,660, NULL);
renderTexture(textBox(buffer[10], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, 554,660, NULL);
renderTexture(textBox(buffer[11], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, 821,660, NULL);
When this segment is placed into the main game loop as follows the memory leak occurs:
while (testState == 1) {
renderTexture(textBox(buffer[0], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, cooridnates[0][0], cooridnates[1][1], NULL);
SDL_RenderPresent(renderer);
while (SDL_PollEvent( & buttonPress)) {
// get global mouse state for all subroutines to use
// SDL_GetMouseState( & xMouse, & yMouse);
if (SDL_GetMouseState( & xMouse, & yMouse) & SDL_BUTTON(1) == 1) {
for(Z = 0; Z <= 11; Z++) {
if (isPressed(boundaries[Z][0],boundaries[Z][1],boundaries[Z][2],boundaries[Z][3]) == 1) {
boxState[Z] = 1;
} else boxState[Z] = 0;
}
}
//asm
if (xMouse > 10 && xMouse <= 210 && yMouse > 10 && yMouse <= 210) {
if (SDL_GetMouseState( & xMouse, & yMouse) & SDL_BUTTON(1) == 1) {
renderTexture(asmSheet, renderer, 10, 10, & asmClips[0]);
saveFile = fopen(savePath, "w");
for(Z = 0; Z <= 11; Z++){
fprintf(saveFile,"@\n%s\n",buffer[Z]);
}
fclose(saveFile);
} else {
renderTexture(asmSheet, renderer, 10, 10, & asmClips[1]);
}
} else {
renderTexture(asmSheet, renderer, 10, 10, & asmClips[2]);
}
//start
if (xMouse > 210 && xMouse <= 410 && yMouse > 10 && yMouse <= 210) {
if (SDL_GetMouseState( & xMouse, & yMouse) & SDL_BUTTON(1) == 1) {
renderTexture(startSheet, renderer, 210, 10, & startClips[0]);
} else {
renderTexture(startSheet, renderer, 210, 10, & startClips[1]);
}
} else {
renderTexture(startSheet, renderer, 210, 10, & startClips[2]);
}
if (xMouse > 410 && xMouse <= 610 && yMouse > 10 && yMouse <= 210) {
if (SDL_GetMouseState( & xMouse, & yMouse) & SDL_BUTTON(1) == 1) {
renderTexture(stopSheet, renderer, 410, 10, & stopClips[0]);
//stop
} else {
renderTexture(stopSheet, renderer, 410, 10, & stopClips[1]);
}
} else {
renderTexture(stopSheet, renderer, 410, 10, & stopClips[2]);
}
if (xMouse > 610 && xMouse <= 810 && yMouse > 10 && yMouse <= 210) {
if (SDL_GetMouseState( & xMouse, & yMouse) & SDL_BUTTON(1) == 1) {
renderTexture(stepSheet, renderer, 610, 10, & stepClips[0]);
//step
} else {
renderTexture(stepSheet, renderer, 610, 10, & stepClips[1]);
}
} else {
renderTexture(stepSheet, renderer, 610, 10, & stepClips[2]);
}
renderTexture(tnode0, renderer, 10, 220, NULL);
renderTexture(tnode1, renderer, 277, 220, NULL);
renderTexture(tnode2, renderer, 544, 220, NULL);
renderTexture(tnode3, renderer, 811, 220, NULL);
renderTexture(tnode4, renderer, 10, 430, NULL);
renderTexture(tnode5, renderer, 277, 430, NULL);
renderTexture(tnode6, renderer, 544, 430, NULL);
renderTexture(tnode7, renderer, 811, 430, NULL);
renderTexture(tnode8, renderer, 10, 640, NULL);
renderTexture(tnode9, renderer, 277, 640, NULL);
renderTexture(tnode10, renderer, 544, 640, NULL);
renderTexture(tnode11, renderer, 811, 640, NULL);
for(Z = 0; Z <= 11; Z++) {
if (boxState[Z] == 1) {
if (buttonPress.type == SDL_TEXTINPUT || buttonPress.type == SDL_KEYDOWN) {
if (buttonPress.type == SDL_KEYDOWN && buttonPress.key.keysym.sym == SDLK_BACKSPACE && strlen(buffer[Z]) > 1) {
buffer[Z][strlen(buffer[Z]) - 1] = '\0';
renderTexture(textBox(buffer[Z], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, cooridnates[Z][0], cooridnates[Z][1], NULL);
} else if (buttonPress.type == SDL_TEXTINPUT) {
strcat(buffer[Z], buttonPress.text.text);
renderTexture(textBox(buffer[Z], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, cooridnates[Z][0], cooridnates[Z][1], NULL);
}
if (buttonPress.key.keysym.sym == SDLK_RETURN) {
strcat(buffer[Z], "\n ");
renderTexture(textBox(buffer[Z], TTF_OpenFont(fontLocation, 14), color, renderer, 200), renderer, cooridnates[Z][0], cooridnates[Z][1], NULL);
}
}
}
}
}
//update frame
}
IMG_Quit();
SDL_Quit();
}
I have already tried to destroy the textures using sdl_destroytexture
, but it doesn't seem to help. Can anyone suggest a way to fix this?
the textBox function is as folows:
SDL_Texture *textBox(char tempBuffer[], TTF_Font* font, SDL_Color color, SDL_Renderer *renderer, int maxLength){
int w,h;
//TTF_SizeText(font, tempBuffer, &w, &h);
SDL_Surface * Surface = TTF_RenderText_Blended_Wrapped(font, tempBuffer, color, maxLength);
if(Surface == NULL) {
logSDLError("TextboxCreate");
} else {
SDL_Texture * Texture = SDL_CreateTextureFromSurface(renderer, Surface);
if(Texture == NULL) {
logSDLError("TextboxCreate");
} else {
return Texture;
}
}
}
```
TTF_CloseFont
insidetextbox
? \$\endgroup\$TTF_OpenFont
each frame. Load the font file(s) at application startup and destroy it/them at application shutdown. \$\endgroup\$