SDL_DestroyWindow doesn't free memory - c++

Basically, in my program I have to create and destroy a window. I always use the same window pointer creating and destroying the contents (texture and render).
I notice a memory leak in this process so I wrote a simple program to verify this, here the code.
The problem has the higher impact on Windows, on Ubuntu at the end of the test the memory is increased only around 3MB (around 236MB on Windows).
#include <iostream>
#include "SDL.h"
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* mainWindow;
SDL_Renderer* mainRenderer;
SDL_Texture* mainTexture;
for (int i = 0; i < 200; i++)
{
mainWindow = SDL_CreateWindow("Memory Leak Test v1.0", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, SDL_WINDOW_SHOWN);
mainRenderer = SDL_CreateRenderer(mainWindow, -1, SDL_RENDERER_ACCELERATED);
mainTexture = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, 320, 240);
if (i == 0)
{
std::cout << "SDL Memory Leak Tester, please check the amount of memory\noccupied by the process, then press Enter\n";
getchar();
}
SDL_Delay(50);
if (i == 199)
{
std::cout << "SDL Memory Leak Tester, please check the amount of memory\noccupied by the process, then press Enter\n";
getchar();
}
SDL_DestroyTexture(mainTexture);
SDL_DestroyRenderer(mainRenderer);
SDL_DestroyWindow(mainWindow);
}
std::cout << "Test finished, press Enter to close\n";
getchar();
return 0;
}
Any idea?

Related

SDL: Blitting BMP to window surface black screen mystery

I've written the following code to load a BMP image as a surface and then blit that image onto the window:
#include "stdafx.h"
#include "SDL.h"
#include <iostream>
int main(int argc, char *argv[])
{
//init
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("Playground", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 500, 500, 0);
std::cout << SDL_GetError() << std::endl;
SDL_Surface* surface = SDL_GetWindowSurface(window);
//load file and convert to texture
SDL_Surface* bmp = SDL_LoadBMP("sample.bmp");
std::cout << SDL_GetError() << std::endl;
//render texture
SDL_Rect area;
area.x, area.y = 3;
area.h, area.w = 25;
SDL_BlitSurface(bmp, &area, surface, &area);
std::cout << SDL_GetError() << std::endl;
SDL_UpdateWindowSurface(window);
std::cout << SDL_GetError() << std::endl;
SDL_Delay(3000);
//clean up
SDL_FreeSurface(bmp);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
When I press F5 (I'm working in Visual Studio Express 2017) to build and run the program, the program created runs, creates a window, and then the window remains entirely black as the program runs. I receive no error messages from V.S., SDL_GetError(), or Windows.
There appears to be no problems but the image just gets lost somewhere, it seems. Would anyone be able to help me?
P.S. Here is the bmp I am trying to display:
This code doesn't do what you think it does:
area.x, area.y = 3;
area.h, area.w = 25;
You should change it to
area.x = area.y = 3;
area.h = area.w = 25;
to have multiple assignments. Or even better just initialize SDL_Rect inline:
SDL_Rect area = { 3, 3, 25, 25 };

SDL_LoadBMP() displaying a black surface while surface is referenced

Trying to load an image onto an SDL_Surface. However the surface is always black although the bmp is clearly not.
NOTE
This is a working SDL_Window and creating a surface pointer is successful, what is unsuccessful is loading "Kassadin.bmp" which is located in the Code::Blocks project folder. It displays a black surface.
ALL answers on this particular question have NOT solved this problem, before marking this as a duplicate.
#include <iostream>
#include <SDL.h>
#include <stdio.h>
using namespace std;
const int SCREEN_WIDTH = 700;
const int SCREEN_HEIGHT = SCREEN_WIDTH / 12 * 9;
//Create an SDL_Window pointer
SDL_Window* window = NULL;
//Create an SDL_Surface pointer
SDL_Surface* surface = NULL;
//SDL_Surface for an image
SDL_Surface* imgSurface = NULL;
bool init(){
//try init SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0){
cout << "Failed init SDL" << endl;
return false;
}else{
//create window title x pos y pos width height flags
//This doesnt include a surface ie it will be a plain window
window = SDL_CreateWindow("An SDL Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
}
if(window == NULL){
cout << "Failed creating SDL window" << endl;
return false;
}else{
// creates surface with an SDL_Window object
surface = SDL_GetWindowSurface(window);
}
return true;
}
bool loadMedia(){
imgSurface = SDL_LoadBMP("Kassadin.bmp");
return true;
}
void close(){
//Sets the SDL_Window pointer to NULL again
SDL_DestroyWindow(window);
window = NULL;
SDL_FreeSurface (imgSurface);
imgSurface = NULL;
//quits
SDL_Quit();
}
int main(int argc, char* argv[]){
if(!init()){
cout << "error init sdl" << endl;
}else{
if(!loadMedia){
cout << "Trouble loading media..." << endl;
}else{
SDL_BlitSurface(imgSurface, NULL, surface, NULL);
}
}
//This is so it's not just a static window ie it can update
SDL_UpdateWindowSurface(window);
SDL_Delay(5000);
close();
return 0;
}
Problemmatic line is
if(!loadMedia){
It is not a function call. What it does is checks address of function loadMedia is NULL, which is always false because function address assigned by linker (as opposed to funciton pointers which you manually assign at runtime).
As you mentioned codeblocks, I suppose you use gcc to compile your code. If only you've added at least -Wall flag (which is a very good practice) compiler would have warned you that you're doing something that very much looks like a mistake:
test2.cpp:70:9: warning: the address of ‘bool loadMedia()’ will always evaluate as ‘true’ [-Waddress]

SDL_Texture is not being set

I am having troubles with SDL_Texture
RPGTutorial.cpp
#include "stdafx.h"
int main(int argc, char *argv[])
{
bool quit = false;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = NULL;
window = SDL_CreateWindow("RPG Tutorial!", 100, 100, 600, 400, SDL_WINDOW_SHOWN);
if (window == NULL)
{
std::cout << "Window couldn't be created" << std::endl;
return 0;
}
SDL_Renderer* renderer = NULL;
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL)
{
std::cout << "Renderer is not being created!" << std::endl;
SDL_DestroyWindow(window);
system("PAUSE");
return 0;
}
SDL_Event* mainEvent = new SDL_Event();
SDL_Texture* grass = NULL;
grass = IMG_LoadTexture(renderer, "Grass.bmp");
if (grass == NULL)
{
std::cout << "Grass Image was not found!" << std::endl;
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
delete mainEvent;
system("PAUSE");
return 0;
}
SDL_Rect grass_rect;
grass_rect.x = 0;
grass_rect.y = 0;
grass_rect.w = 64 * 2;
grass_rect.h = 64 * 2;
while (!quit && mainEvent->type != SDL_QUIT)
{
SDL_PollEvent(mainEvent);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, grass, NULL, &grass_rect);
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(window);
SDL_DestroyRenderer(renderer);
delete mainEvent;
return 0;
}
stdafx.h
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_mixer.h>
#include <iostream>
I have the Grass.bmp in the RPGTutorial->RPGTutorial->Grass.bmp
When I compile it, it is successful. It runs through the code til I get to the part where it checks if(grass == NULL) and it goes through that and exits. Can someone help me know why my grass is not being set to the image when I have the image in the same folder that the .cpp files are in? I even tried adding an Image folder to hold it in, and it did not work either.
If you have the time, I recommend you take some time to go through the Lazyfoo tutorials they are fantastic. He mentions this issue in the second tutorial, "Getting an Image on the Screen."
Visual Studio changes your current working directory to the place where your .vcxproj file is. That will be the directory you want to place your resources in. If you're not sure where that is, you can use the _getcwd() function in the direct.h header MSDN Source For getcwd

Why the game window closes after specific time?

Why the window that created by SDL Game Library are automatically closed after specific time.
I know the reason is SDL_Delay() function, but if not used that function, the game will appear runtime error.
How can I create a window that continuously work without appear in specific period time ?
My code(Simplest code):
SDL_Window *window;
SDL_Renderer *render;
int main(int argc, char* args[]){
if(SDL_Init(SDL_INIT_EVERYTHING) >= 0){
window = SDL_CreateWindow("Simple game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_SHOWN);
if(window != 0){
render = SDL_CreateRenderer(window, -1, 0);
}
}else{
return 1;
}
SDL_SetRenderDrawColor(render, 0, 0, 0, 255);
SDL_RenderClear(render);
SDL_RenderPresent(render);
SDL_Delay(3000);
SDL_Quit();
return 0
}
You need to loop forever and call SDL update screen functions. Read LazyFoo tutorials found here: http://lazyfoo.net/SDL_tutorials
Or here a short code to get you started:
#include <iostream>
#include "SDL/SDL.h" // basic SDL
#include <string>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BBP = 32; // bits per-pixel
SDL_Surface* screen = NULL; // display screen
SDL_Event event; // grab events
using namespace std;
bool init() {
// initialize SDL
if(SDL_Init( SDL_INIT_EVERYTHING ) == -1)
return false;
//the screen image
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT,
SCREEN_BBP, SDL_SWSURFACE );
if(!screen) {
cout << "error creating screen" << endl;
return false;
}
//Set the window caption
SDL_WM_SetCaption("Event Test", NULL );
return true;
}
int main(int argc, char* argv[])
{
try
{
// make sure the program waits for a quit
bool quit = false;
cout << "Starting SDL..." << endl;
// Start SDL
if(!init()) {
cout << "initialize error" << endl;
return false;
}
// main loop
while( quit == false )
{
if (SDL_PollEvent(&event))
{
// The x button click
if(event.type == SDL_QUIT)
{
//quit the program
quit = true;
}
}
// Fill the screen white
SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB(
screen->format, 0xFF, 0xFF, 0xFF ) );
//Update screen
if(SDL_Flip(screen) == -1)
return -1;
}
}
catch (exception& e)
{
cerr << "exception caught: " << e.what() << endl;
return -1;
}
return 0;
}

C++ game loop example

Can someone write up a source for a program that just has a "game loop", which just keeps looping until you press Esc, and the program shows a basic image. Heres the source I have right now but I have to use SDL_Delay(2000); to keep the program alive for 2 seconds, during which the program is frozen.
#include "SDL.h"
int main(int argc, char* args[]) {
SDL_Surface* hello = NULL;
SDL_Surface* screen = NULL;
SDL_Init(SDL_INIT_EVERYTHING);
screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
hello = SDL_LoadBMP("hello.bmp");
SDL_BlitSurface(hello, NULL, screen, NULL);
SDL_Flip(screen);
SDL_Delay(2000);
SDL_FreeSurface(hello);
SDL_Quit();
return 0;
}
I just want the program to be open until I press Esc. I know how the loop works, I just don't know if I implement inside the main() function, or outside of it. I've tried both, and both times it failed. If you could help me out that would be great :P
Here is a complete and working example. Instead of using a frame-time regulation you can also use SDL_WaitEvent.
#include <SDL/SDL.h>
#include <cstdlib>
#include <iostream>
using namespace std;
const Uint32 fps = 40;
const Uint32 minframetime = 1000 / fps;
int main (int argc, char *argv[])
{
if (SDL_Init (SDL_INIT_VIDEO) != 0)
{
cout << "Error initializing SDL: " << SDL_GetError () << endl;
return 1;
}
atexit (&SDL_Quit);
SDL_Surface *screen = SDL_SetVideoMode (640, 480, 32, SDL_DOUBLEBUF);
if (screen == NULL)
{
cout << "Error setting video mode: " << SDL_GetError () << endl;
return 1;
}
SDL_Surface *pic = SDL_LoadBMP ("hello.bmp");
if (pic == NULL)
{
cout << "Error loading image: " << SDL_GetError () << endl;
return 1;
}
bool running = true;
SDL_Event event;
Uint32 frametime;
while (running)
{
frametime = SDL_GetTicks ();
while (SDL_PollEvent (&event) != 0)
{
switch (event.type)
{
case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_ESCAPE)
running = false;
break;
}
}
if (SDL_GetTicks () - frametime < minframetime)
SDL_Delay (minframetime - (SDL_GetTicks () - frametime));
}
SDL_BlitSurface (pic, NULL, screen, NULL);
SDL_Flip (screen);
SDL_FreeSurface (pic);
SDL_Delay (2000);
return 0;
}
Tried with something like
SDL_Event e;
while( SDL_WaitEvent(&e) )
{
if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE) break;
}
? You can find many tutorials and example out there; just a fast-search example.
Added note: WaitEvent "freezes" the program so you can't do anything .. you just wait; other waiting technics can be desired (as PollEvent, or WaitEvent again after the initializtion of a timer).
Since you're already using SDL, you could use the SDL_PollEvent function to run an event loop, checking to see if the key press event was ESC. Looks like this would be along the lines of mySDL_Event.key.keysym.sym == SDLK_ESCAPE.
#include <conio.h>
...
while (!kbhit())
{
hello = SDL_LoadBMP("hello.bmp");
SDL_BlitSurface(hello, NULL, screen, NULL);
SDL_Flip(screen);
}
...