I'm just trying to create a simple SDL2 window with a simple renderer. When I debug it, it runs normally, the memory still normal. But when I minimize it, press the minimize button then suddenly the memory just keep going up and only when i reopened that window then the memory goes back normal.
Memory spike
The code:
#include <SDL.h>
#include <SDL_image.h>
int main(int argc, char* args[]) {
SDL_Window* gWindow;
SDL_Renderer* gRenderer;
SDL_Texture* gTexture;
SDL_Surface* temp;
//Init
SDL_Init(SDL_INIT_VIDEO);
gWindow = SDL_CreateWindow("Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1366, 768, SDL_WINDOW_SHOWN);
gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED);
IMG_Init(IMG_INIT_PNG);
//loading medias
temp = IMG_Load("assets/sprites/700.png");
gTexture = SDL_CreateTextureFromSurface(gRenderer, temp);
SDL_FreeSurface(temp);
//The main loop
bool quit = false;
SDL_Event e;
while (!quit)
{
while (SDL_PollEvent(&e) != 0)
{
if (e.type == SDL_QUIT)
{
quit = true;
}
}
SDL_RenderClear(gRenderer);
SDL_RenderCopy(gRenderer, gTexture, NULL, NULL);
SDL_RenderPresent(gRenderer);
}
//Destroy things
SDL_DestroyTexture(gTexture);
gTexture = NULL;
SDL_DestroyRenderer(gRenderer);
SDL_DestroyWindow(gWindow);
gWindow = NULL;
gRenderer = NULL;
IMG_Quit();
SDL_Quit();
return 0;
}
switch (m_event.window.event)
{
case SDL_WINDOWEVENT_MINIMIZED:
while (SDL_WaitEvent(&m_event))
{
if (m_event.window.event == SDL_WINDOWEVENT_RESTORED)
{
break;
}
}
break;
...
So when you minimize the Window, SDL keeps waiting for events. No further code could memory leak, since it stays in the lazy polling loop until the window is restored.
I traced the leak back to SDL_RenderClear, which shouldn't be supposed to run while minimized.
I just ran your code and compiled it. Seems fine. However you did mention when you minimize the program your ram meter increases, how long are you able to perform this repetition before it crashes? and does it even crash? It could be normal behavior. If your program crashes, its a memory leak which could indicate forgetting to de-allocate some other pointer to a memory object/variable.
Related
I'm trying to test a simple SDL2 application. The app runs without any errors. However, no window shows up.
I'm using Ubuntu18.04 on a VMWare machine. I also tried to compile SDL from the source but got the same result. I am unsure if the cause of the problem is related to my OS or because of executing from a virtual machine.
Here is a simple application from docs (I just added SDL_GetNumDisplayModes to make sure the display mode is OK- returns 1)
// Using SDL and standard IO
#include <SDL2/SDL.h>
#include <stdio.h>
// Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
int main(int argc, char *args[])
{
// The window we'll be rendering to
SDL_Window *window = NULL;
// The surface contained by the window
SDL_Surface *screenSurface = NULL;
// Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
}
else
{
int res = SDL_GetNumDisplayModes(0);
printf("SDL_GetNumDisplayModes: %d\r\n", res);
// Create window
window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (window == NULL)
{
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
}
else
{
// Get window surface
screenSurface = SDL_GetWindowSurface(window);
// Fill the surface white
SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF));
// Update the surface
SDL_UpdateWindowSurface(window);
// Hack to get window to stay up
SDL_Event e;
bool quit = false;
while (quit == false)
{
while (SDL_PollEvent(&e))
{
if (e.type == SDL_QUIT)
{
quit = true;
}
}
}
}
}
// Destroy window
SDL_DestroyWindow(window);
// Quit SDL subsystems
SDL_Quit();
return 0;
}
My SDL program wont work. It was supposed to change the image when I pressed Up. However, it changes the image only when I click on the x in the Window
#include "SDL.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
int main(int argc, char* argv[])
{
enum KeyPressSurfaces {
KEY_PRESS_SURFACE_DEFAULT,
KEY_PRESS_SURFACE_UP,
KEY_PRESS_SURFACE_LEFT,
KEY_PRESS_SURFACE_RIGHT,
KEY_PRESS_SURFACE_DOWN,
KEY_PRESS_SURFACE_TOTAL
};
SDL_Init(SDL_INIT_VIDEO);
SDL_Event e;
SDL_Window* window = SDL_CreateWindow("antena1", // window's title
10, 25, // coordinates on the screen, in pixels, of the window's upper left corner
640, 420, // window's length and height in pixels
SDL_WINDOW_OPENGL);
SDL_Surface* key_press_surface[KEY_PRESS_SURFACE_TOTAL];
SDL_Surface* gImage = NULL;
SDL_Surface* gScreenSurface = NULL;
bool quit = false;
key_press_surface[KEY_PRESS_SURFACE_UP] = SDL_LoadBMP("hello_world.bmp");
gScreenSurface = SDL_GetWindowSurface(window);
gImage = SDL_LoadBMP("nick.bmp");
if (gImage == NULL) {
printf("Erro", SDL_GetError);
}
SDL_BlitSurface(gImage, NULL, gScreenSurface, NULL);
SDL_UpdateWindowSurface(window);
gScreenSurface = SDL_GetWindowSurface(window);
while (!quit) {
while (SDL_PollEvent(&e) == 0) {
if (e.type == SDL_QUIT) {
quit = true;
//SDL_DestroyWindow(window);#
}
else if (e.type == SDL_KEYDOWN) {
switch (e.key.keysym.sym) {
case SDLK_LEFT:
gImage = key_press_surface[KEY_PRESS_SURFACE_UP];
break;
default:
gScreenSurface = NULL;
break;
}
}
}
};
SDL_BlitSurface(gImage, NULL, gScreenSurface, NULL);
SDL_UpdateWindowSurface(window);
SDL_Delay(30000);
return 0;
}
https://wiki.libsdl.org/SDL_PollEvent
SDL_PollEvent returns 0 if there are no events available. So per the example in the above article, in order to get into the while statement for SDL_PollEvent, there must be events in the queue. However, your code only goes into the loop if there are NO events in the queue. So anything that happens once you get there is undefined.
IOW, just remove the "== 0".
I'm trying to simply create a window and blit an image to the screen but for some reason the image is not showing up and the screen remains white. I've been using lazyfoo's tutorial for reference in order to figure this out. I posted all my code below, hopefully it's readable enough. Help would be appreciated as I've been stuck on this for an hour or two, thank you.
#include <SDL.h>
#include <SDL_audio.h>
#include <cstdio>
#include <iostream>
#include <Windows.h>
// creates Load_surface function
SDL_Surface *loadSurface(std::string path) {
SDL_Surface *loadedSurface = SDL_LoadBMP(path.c_str());
if (loadedSurface == NULL) {
printf("Unable to load image %s! SDL Error: %s\n", path.c_str(),
SDL_GetError());
}
return loadedSurface;
}
int main(int argc, char ** argv)
{
// pointer variable for window
SDL_Window *window;
SDL_Surface *surface = NULL;
SDL_Surface *media =
loadSurface("C:\\Users\\nickl\\Desktop\\buttonpressed.bmp");
// initialize and test for failure
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) == -1) {
return 1;
}
// create the window
window = SDL_CreateWindow(
"Ice Cream Boys Software",
48,
48,
640,
480,
SDL_WINDOW_OPENGL
);
// safety check, see if window was created, otherwise throw an error
if (window = NULL) {
printf("Could not create window: %s", SDL_GetError());
return 1;
}
else {
OutputDebugString(TEXT("Surface loaded.\n"));
surface = SDL_GetWindowSurface(window);
}
SDL_BlitSurface(media, NULL, surface, NULL);
SDL_UpdateWindowSurface(window);
/* ************************************** loop **************************** */
// bool to keep window open and event handler
bool quit = false;
SDL_Event e;
// loop to keep window open
while (!quit) {
while (SDL_PollEvent(&e) != 0) {
if (e.type == SDL_QUIT) {
quit = true;
}
else if (e.type == SDL_KEYDOWN) {
OutputDebugString(TEXT("My output string.\n"));
}
}
}
/* ************************************************************************** */
// close and destroy window
SDL_DestroyWindow(window);
// quit
SDL_Quit();
return 0;
}
i stuck in a big bug with my code which i can't open the first window of my game after running it! it just open blank for a few secondes and then it closes automatically. I doon't know what wrong with my code beacause i'm following series of tutorials and my code seems like the code in the tutorials. here's my code:
#include "stdafx.h"
#include "FirstClass.h"
FirstClass::FirstClass(void){
bool quit = false;
window = NULL;
window = SDL_CreateWindow("Snaykie v1.0",350, 150, 800, 500, SDL_WINDOW_SHOWN);
if (window == NULL){
std::cout << "Can not open the game!" << std::endl;
}
renderer = NULL;
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
evt = new SDL_Event();
//background image
txt = NULL;
txt = IMG_LoadTexture(renderer, "mainview.bmp");
rct.x = 0 ;
rct.y = 0;
rct.h = 500;
rct.w = 800;
//button start
sbutt = NULL;
sbutt = IMG_LoadTexture(renderer, "startbutton.bmp");
startrct.x = 0 ;
startrct.y = 0;
startrct.h = 100;
startrct.w = 100;
}
FirstClass::~FirstClass(void)
{
SDL_DestroyTexture(txt);
SDL_DestroyTexture(sbutt);
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
delete evt;
}
//the code below is the loops that let the window stucks forever to keep opened
void FirstClass :: GameStart(void){
while (!quit && evt->type != SDL_QUIT){
SDL_PollEvent(evt);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, txt, NULL, &rct);
SDL_RenderCopy(renderer, sbutt, NULL, &startrct);
SDL_RenderPresent(renderer);
}
}
Please help me and thanks i'm really in a big problem.
You are handling the evt variable in a bad way. It is allocated but not initialized, and you compare the uninitialized value to SDL_QUIT. You should reorder the code inside FirstClass::GameStart and preferably use a local variable (since there is no actual need to use a dynamically allocated one) and remove the allocation and deletion of the existing evt from constructor and destructor. Here is a better version of FirstClass::GameStart:
void FirstClass::GameStart(void){
SDL_Event evt;
while (SDL_PollEvent(&evt)){
if (evt.type == SDL_QUIT) {
// a user requested termination has been received, exit the loop
break;
}
else {
// filter the event?
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, txt, NULL, &rct);
SDL_RenderCopy(renderer, sbutt, NULL, &startrct);
SDL_RenderPresent(renderer);
}
}
}
Also ensure that you are actually invoking the FirstClass::GameStart funcion from main, maybe you are simply not running the event loop at all.
I'm using SDL2 on Windows with Code::blocks.
I write this little program. But it cause a memory leak!
The code is very simple. it does only clear and update the screen.
#include <SDL.h>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
SDL_Event event;
bool quit = false;
void loadSDL();
void closeSDL();
int main( int argc, char* args[] )
{
loadSDL();
while(!quit)
{
while(SDL_PollEvent(&event) != 0)
{
if(event.type == SDL_QUIT)
{
quit = true;
}
}
SDL_RenderClear( renderer );
SDL_RenderPresent( renderer );
}
closeSDL();
return 0;
}
void loadSDL()
{
SDL_Init( SDL_INIT_VIDEO );
window = SDL_CreateWindow( "Test1", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN );
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawColor(renderer, 0x0, 0x0, 0x0, 0xFF);
}
void closeSDL()
{
SDL_DestroyRenderer( renderer );
SDL_DestroyWindow( window );
window = NULL;
renderer = NULL;
SDL_Quit();
}
I don't know what is wrong...
If I comment this line out
SDL_RenderClear( renderer );
There is no memory leak!
Memory leaks are not the most obvious things to track down. To properly identify a leak, you'll need to use a profiling tool as mentioned in the comments.
The most common reason for what you are seeing is that the OS is free to assign memory to processes before they request it and to delay releasing unused memory. Sometimes this looks like a leak as your process's RAM usage grows in Task Manager. If you wait for a while, it will likely stabilize.
As for a leak specifically in SDL_RenderClear(), it helps to know which renderer you're using. They have different code paths. However, in this case they are quite similar. Here's the GL version from SDL_render_gl.c:
static int
GL_RenderClear(SDL_Renderer * renderer)
{
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
GL_ActivateRenderer(renderer);
data->glClearColor((GLfloat) renderer->r * inv255f,
(GLfloat) renderer->g * inv255f,
(GLfloat) renderer->b * inv255f,
(GLfloat) renderer->a * inv255f);
data->glClear(GL_COLOR_BUFFER_BIT);
return 0;
}
The only indirect call here is GL_ActivateRenderer(), which does a simple comparison and set. The Direct3D RenderClear() is a little more complicated but does essentially the same thing. It is unlikely that your problem is here.