elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Memory leak ~~new + delete + SDL~~
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Memory leak ~~new + delete + SDL~~  (Leído 2,098 veces)
Ceiplusplus

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Memory leak ~~new + delete + SDL~~
« en: 4 Julio 2016, 17:54 pm »

Hola a todos, tengo una gran duda desde hace unos 2 días y no consigo resolverla, espero que podáis echarme una mano :-\
estoy programando un minijuego en C++ y SDL. El problema esta dentro de la clase Imagen, la cual utilizo para almacenar una imagen y sus propiedades, al crear un objeto de esta clase utilizando memoria dinámica y posteriormente borrándolo, este sigue consumiendo la misma memoria que tenía una vez hecha la reserva y no entiendo muy bien el por qué. Os pongo aquí el fragmento de código que utilicé para intentar descubrir que es lo que fallaba.
-------------------------------------------

#include <iostream>
#include <SDL.h>
#include <SDL_image.h>

class Imagen;

class Imagen
{
private:
   SDL_Texture* m_textura;
   SDL_Renderer* m_renderer;
public:
   Imagen(SDL_Renderer* rend, std::string ruta);
   ~Imagen();
};

#define      FONDO_1         "./Recursos/desarmado.png"

#undef main;

int main(int argc, char* argv)
{
   SDL_Init(SDL_INIT_EVERYTHING);
   IMG_Init(IMG_INIT_PNG);
   bool bandera = true;
   SDL_Window* mi_ventana=NULL;

   mi_ventana=SDL_CreateWindow("Prueba Memory leak", 100, 100, 500, 500, SDL_WINDOW_SHOWN);
   SDL_Renderer* m_renderer=NULL;
   m_renderer = SDL_CreateRenderer(mi_ventana, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
   
   if (m_renderer == NULL)
      std::cout << "Error" << std::endl;

   SDL_Event e;
   Imagen*   m_imagen=NULL;
   
   while (bandera)
   {
      while (SDL_PollEvent(&e) != 0)
      {
         if (e.type == SDL_KEYDOWN)
         {
            if (e.key.keysym.sym == SDLK_c) //cargamos imagen
            {
               m_imagen = new Imagen(m_renderer, FONDO_1);
            }
            else if (e.key.keysym.sym == SDLK_r)// descargamos imagen
            {
               if (m_imagen != NULL)
               {
                  delete(m_imagen);
                  m_imagen = NULL;
                  std::cout << "Borrando..." << std::endl;
               }
            }
         }
         else if (e.type == SDL_QUIT)
         {
            bandera = false;
         }
      }

      SDL_Delay(50);
   }

   SDL_Quit();
   IMG_Quit();

   return 0;
}

Imagen::Imagen(SDL_Renderer* rend, std::string ruta):m_renderer(rend), m_textura(NULL)
{
   SDL_Surface* m_superficie = NULL;
   SDL_Texture* m_textura = NULL;

   m_superficie = IMG_Load(FONDO_1);

   m_textura = SDL_CreateTextureFromSurface(m_renderer, m_superficie);

   if (m_superficie != NULL)
      SDL_FreeSurface(m_superficie);
}

Imagen::~Imagen()
{
   SDL_DestroyTexture(m_textura);
   m_textura = NULL;
}


-------------------------------------------
El programa funciona tal que así:

empiezo inicializando una ventana (SDL_window*) y creo un contexto (SDL_Renderer*) para dibujar en pantalla y poder transformar las superficies (imagen) en texturas (como las superficies pero se dibujan mas rápido en pantalla o eso tengo entendido :laugh:), posteriormente declaro un puntero a un objeto Imagen, y creo un bucle donde se realizan dos operaciones, al pulsar 'c' del teclado creo un objeto de la clase Imagen que carga una imagen determinada, y al pulsar 'r' borro el objeto creado.

En el fragmento de código utilizo SDL.h y SDL_image.h

PD: Las funciones SDL_FreeSurface y SDL_DestroyTexture funcionan correctamente, el problema viene al meter como miembro de una clase, SDL_Texture* y hacer las operaciones dentro de la clase.

Espero respuestas gracias de antemano ;D


En línea

AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.619


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Memory leak ~~new + delete + SDL~~
« Respuesta #1 en: 4 Julio 2016, 18:06 pm »

Como estas validando la cantidad de memoria utilizada?

ten en cuenta que cuando se libera un segmento de memoria esto solo me marca como "Libre", pero no significa que esa memoria (Asignada por el sistema Operativo) va a dejar de pertenecer al programa de forma instantánea, eso es tarea del sistema operativo que después de un tiempo de no utilizar la memoria, se le des-Asigna al programa.

Por ejemplo he hecho programas que cargan el contenido de un archivo en memoria y por la forma en la que esta hecho al principio sube hasta los 200MB de memoria usada y despues de unos varios minutos de estar procesando mas datos, va bajando a lo que realemnte esta usando unos 10-15 MB que es cuando ya se dejo de usar mucha memoria y el sistema se la des-asigno al proceso.

Saludos


En línea

Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW
Ceiplusplus

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Re: Memory leak ~~new + delete + SDL~~
« Respuesta #2 en: 4 Julio 2016, 19:31 pm »

En visual studio, con las herramientas de diagnostico se puede mirar la cantidad de memoria utilizada en la aplicación cuando cargo la imagen, esto es, creo un objeto y en el objeto cargo la imagen. Las pruebas que he hecho son las siguientes:

en el main, cree una instancia SDL_Texture y le cargué una imagen, al cargarla, en las herramientas de diagnostico subió la memoria y al borrar el SDL_Texture vuelve al estado de memoria inicial al que estaba antes de cargar la imagen. (Esto es lo que creo que debería hacer el programa siempre).

La otra prueba, es hacer exactamente lo mismo pero el SDL_Texture esta dentro de un objeto de la clase Imagen, al crear el objeto, la memoria sube, y al borrarlo, se mantiene esa memoria, como si el objeto siguiera existiendo.

He probado lo que me dijiste, pero después de varios minutos de esperar tras haber borrado el objeto (aprox. 4 minutos) la memoria sigue estando en el mismo punto.

¿Hay alguna forma de arreglarlo?
No se si será el problema de que C++ no tiene el 'colector de basura' como tiene java o c# pero debe de haber alguna forma para hacer que esto no pase ¿no?

Por cierto, gracias por la respuesta AlbertoBSD.
En línea

AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.619


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Memory leak ~~new + delete + SDL~~
« Respuesta #3 en: 4 Julio 2016, 20:46 pm »

Ahi desconozco como se comporte, igual podrias darle mas tiempo al programa ooo tratar de liberar la instancia del objeto a ver si ahora si libera toda esa memoria referenciada por el objeto.

Saludos
En línea

Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW
Ceiplusplus

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Re: Memory leak ~~new + delete + SDL~~
« Respuesta #4 en: 5 Julio 2016, 15:35 pm »

¿como libero la instancia del objeto?
Resulta que en el juego que estoy haciendo tengo varias plantillas de animaciones por lo que me obliga a estar cambiando de imágenes constantemente, es decir creando y destruyendo la clase Imagen, esto es:
el personaje coge arma a dos manos, descargo las imágenes de las animaciones anteriores del personaje y cargo ahora las de 2 manos.

He estado mirando por internet pero no mucha gente da información acerca del problema, hay gente que aconseja los smart pointers pero no funcionan bien en el sentido de que debes estar constantemente creándolos, pues mucho de ellos solo trabajan en el bloque que los creas y sinceramente he probado cambiar los contenidos del smart pointer y no encuentro la manera.

Otra posible solución que ya he probado y no ha funcionado es crear la instancia de la clase dentro de un vector y utilizarunl iterador o los propios métodos del vector para liberar bien la memoria.

 :-X :-X Espero respuesta!! :-X :-X
En línea

Ceiplusplus

Desconectado Desconectado

Mensajes: 4


Ver Perfil
Re: Memory leak ~~new + delete + SDL~~
« Respuesta #5 en: 12 Julio 2016, 18:20 pm »

Ya he corregido lo que pasaba, no se el porqué, ni he conseguido encontrar el porque pasaba en internet, pero lo he solucionado de la siguiente manera, colocar la textura (SDL_Texture*) dentro de un std::vector y con un iterador acceder a la textura almacenada dentro del vector y borrarla utilizando SDL_DestroyTexture (el vector estaba dentro de la clase).  ;-) ;-) ;-)
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[C++] Duda con new y delete[] o delete Tratando de hacer matriz dinamica
Programación C/C++
capsulasinformaticas 7 3,698 Último mensaje 21 Marzo 2013, 18:03 pm
por capsulasinformaticas
Memory leak con strings
Programación C/C++
amchacon 3 1,878 Último mensaje 9 Agosto 2013, 15:25 pm
por Eternal Idol
Duda de novato Resource leak: is never closed
Java
MinW 3 9,701 Último mensaje 20 Diciembre 2013, 13:46 pm
por Mitsu
Memory Leak en código
Programación C/C++
yeray_pg 1 1,255 Último mensaje 1 Noviembre 2014, 11:46 am
por do-while
[Cracked]Vape V3 Leak by ParadiseTeam.
Juegos y Consolas
rigorvzla 3 3,522 Último mensaje 5 Enero 2019, 18:08 pm
por MCKSys Argentina
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines