0

So, whenever I go to debug and run my game, the memory just climbs, As you can see, I wipe the memory after I'm done with it(so I thought) Any tips on managing memory in this state? I have looked at other posts but I'm lost so I need specific help(using Visual Studio 2022/SDL2 libraries) Thank you in advance!

My Code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <iostream>
#include <SDL.h>
#include "SDL_image.h"


class Game
{
public:
    void Run() 
    {
        WinInitialize();
        Render();
        WinShutdown();
    }

private:
    void WinInitialize()
    {
        SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_TIMER);
        
        IMG_Init(1);
        if (!IMG_Init(IMG_INIT_JPG))
        {
            std::cout << "Oh" << IMG_GetError()<< std::endl;
        }
        if (!IMG_Init(IMG_INIT_PNG))
        {
            std::cout << "Oh" << IMG_GetError() << std::endl;
        }
        if (SDL_Init(SDL_INIT_VIDEO) < 0)
        {
            std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
            exit(1);
        }
        
        Window = SDL_CreateWindow(WindowTitle, WidthDefine, HeightDefine, ScreenWidth, ScreenHeight, WindowFlags);
        Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    }

    void Render()
    {
        while (IsRunning)
        {
            SDL_Event event;
            while (SDL_PollEvent(&event))
            {
                if (event.type == SDL_QUIT)
                {
                    IsRunning = false;
                }
                switch (event.type)
                {
                case SDL_KEYDOWN:
                    switch (event.key.keysym.sym)
                    {
                    
                    case SDLK_UP:
                        std::cout << "Up key pressed" << std::endl; // Example action
                        break;
                    case SDLK_DOWN:
                        std::cout << "Down key pressed" << std::endl; // Example action
                        break;
                    case SDLK_LEFT:
                        std::cout << "Left key pressed" << std::endl; // Example action
                        break;
                    case SDLK_RIGHT:
                        std::cout << "Right key pressed" << std::endl; // Example action
                        break;
                    case SDLK_w:
                        std::cout << "W key pressed" << std::endl; // Example action
                        break;
                    case SDLK_s:
                        std::cout << "S key pressed" << std::endl; // Example action
                        break;
                    case SDLK_a:
                        std::cout << "A key pressed" << std::endl; // Example action
                        break;
                    
                    default:
                        break;
                    }
                    break;
                }
            }
            SDL_RenderClear(Renderer); 
            BGtexture = IMG_LoadTexture(Renderer, "SDLMap.jpg");
            SDL_RenderCopy(Renderer, BGtexture, NULL, NULL); // Render background texture
            //SDL_RenderDrawRect(Renderer, &player);
            //PlayerTexture = IMG_LoadTexture(Renderer, "Sdl_Playermodel.jpg");
            //SDL_RenderCopy(Renderer, PlayerTexture, NULL, &player); // Render player texture
            // Game rendering logic goes here
            SDL_RenderPresent(Renderer);
        }
    }

    void WinShutdown()
    {
        SDL_DestroyRenderer(Renderer);
        SDL_DestroyWindow(Window);
        SDL_DestroyTexture(BGtexture);
        SDL_DestroyTexture(PlayerTexture);
        SDL_QuitSubSystem(SDL_INIT_VIDEO);
        SDL_QuitSubSystem(SDL_INIT_EVENTS);
        SDL_QuitSubSystem(SDL_INIT_TIMER);
        IMG_Quit();
        SDL_Quit();
        IsRunning = false;
    }
    int ScreenWidth = 640;
    int ScreenHeight = 480;
    int player_x = 320; int player_y = 240; const int player_w = 100; const int player_h = 100;
    const char* WindowTitle = "SDL_GAME";
    int WidthDefine = SDL_WINDOWPOS_UNDEFINED;
    int HeightDefine = SDL_WINDOWPOS_UNDEFINED;
    Uint32 WindowFlags = SDL_WINDOW_SHOWN;
    bool IsRunning = true;
    SDL_Window* Window = nullptr;
    SDL_Renderer* Renderer = nullptr;
    SDL_Texture* BGtexture = nullptr;
    SDL_Texture* PlayerTexture = nullptr;
    SDL_Rect player = {player_x, player_y, player_w, player_h };
};

int main(int argc, char* argv[])
{
    Game game;
    game.Run();
    return 0;
}

Like I stated I have tried to wipe the memory as recommended by other programmers and forums. I expected the memory to be static, as I'm not writing anything to the CPU, only static images to the GPU. So I'm baffled at the rise in memory by running it.

New contributor
Gustav Con is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
2
  • 4
    You have the answer below, but as a general piece of advice, any time you write a loop you should be asking yourself what really needs to be in this loop, and what can be done before (or after) the loop. Obviously you should not load a texture multiple times, it's not going to be any different the second time you load it.
    – john
    Commented 4 hours ago
  • Yeah, I think I'm a bit sleep deprived, because that should have been obvious to me from the start. Oh well, that's why these forums exist.
    – Gustav Con
    Commented 4 hours ago

1 Answer 1

4

the texture you create with IMG_LoadTexture must be destroyed with SDL_DestroyTexture after you are done with it or it will be leaked, you are creating a new texture on every frame without destroying the old one first.

my recommendation is to use libSDL2pp and SDL::Texture that will automatically do that for you using RAII so you don't need to do manual memory management, same thing applied to the window and the renderer and any surface or texture.

writing the RAII wrappers yourself is not hard either. but i think SDL2pp has good API for beginners, such as making the wrapper implicitly convertible to the wrapped pointer so you don't need to use .get() whenever you want to use it, which you need to do with the following basic wrapper.

inline auto SDL_Texture_deleter=[](SDL_Texture* ptr)
{
    SDL_DestroyTexture(ptr);
};

using SDLTexture = std::unique_ptr<SDL_Texture, decltype(SDL_Texture_deleter)>;

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.