Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

vectores bimensionales dinamicos. ¿Ayuda por favor?

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: vectores bimensionales dinamicos. ¿Ayuda por favor? Responder citando

En el fichero del .h del form creo esto:
Código:

public:      // User declarations
   //**************************************************************************
   //**************************************************************************
   __fastcall TfrmVentas(TComponent* Owner);
   Graphics::TBitmap* BMP[45][120];//Vector bimensional de TBitmap


y en .cpp del fichero creo esto cuando se inicia:
Código:

__fastcall TfrmVentas::TfrmVentas(TComponent* Owner): TForm(Owner)
{
    //Asigno Memoria para 5400 Imagenes
    for(short int i = 0; i < 45; i++)
        for(short int x = 0; x <120>BMP[g][a]->LoadFromFile(Fichero.w_str());
}

/*code........................................*/

        //Cargo en memoria las imagenes necesarias
      if(FileExists(Fichero.w_str()))
           frmVentas->BMP[g][a]->LoadFromFile(Fichero.w_str());



Mas tarde cuando destruyo el formulario hago esto en el evento OnClose

Código:

void __fastcall TfrmVentas::FormClose(TObject *Sender, TCloseAction &Action)
{
    for(short int g = 0; g < 45; g++)
       for(short int a = 0; a < 120; a++)
         delete BMP[g][a];

   MostrarBarraInicio();
}


Hasta ahora todo bien, pero despues de borrar con (delete BMP[g][a]) todos los objetos TBitmap hago una comprobación if(BMP) y siempre es verdadero, también he probado ShowMessage(sizeof(BMP)); y me dá: 21.600 bytes que es lo que ocupan los 5400 punteros.

Los objetos estan declarados como globales al formulario, por ello me pregunto si es que será el forulario el que se encargue de destruir dichos objetos cuando destruyo el formulario.

Tengo esa duda razonable, ya que no quiero dejar en memoria esas imagenes cuando salga de aplicación y sobrecargar la MEMORIA del PC.

Si despues de borrar cada uno de los objetos TBitmap con un bucle for(){} hago esto: delete [] BMP, o delete BMP[], o delete BMP, me dá un error de compilación, y por ello me estaba preguntando que si al ser el VECTOR de TBitmap GLOBAL al formulario seria dicho formulario el encargado de destruirlo.
Necesitaria saber... si alguín me puede ayudar o explicarmelo estaría muy agradecido.
_________________
Muchos hombres no se equivocan jamás porque no se proponen nada razonable.


Ultima edición por JesúsGandia el Mar 25 May, 2010 1:33 am, editado 3 veces
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor
Mensaje    Asunto: Responder citando

JesúsGandia escribió:
pero despues de borrar con (delete BMP[g][a]) todos los objetos TBitmap hago una comprobación if(BMP) y siempre es verdadero, también he probado ShowMessage(sizeof(BMP)); y me dá: 21.600 bytes que es lo que ocupan los 5400 punteros.

"delete" libera la memoria a la que apunta la variable, pero en ningún caso modificara el valor de la variable, por tanto esta seguirá apuntando al mismo sitio aunque este ya no sea válido.

Esto es algo estándar de C++, no es algo específico de C++Builder, citando el estándar: "...the deallocation function will deallocate the storage referenced by the pointer thus rendering the pointer invalid. [Note: the value of a pointer that refers to deallocated storage is indeterminate.]"

Si necesitas reutilizar la variable puedes darle un valor nulo después de liberarla, para así estar seguro de que no intentas liberarla indebidamente una segunda vez..

Y una explicación del creador del lenguaje que puede ser interesante:
http://www2.research.att.com/~bs/bs_faq2.html#delete-zero
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Gracias por contetar tan rapido, Leo.

El vector lo voy ha necesitar durante todo el tiempo que esté la aplicación en memoria, ya que he comprobado que es mucho mas rapido cargar desde la memoria que desde el fichero de imagen en disco. Probado con ciclos de CPU es un 75% mas rapido que cargando desde ficheros en disco. En resumen que no tengo que darles valores NULOS porque no las voy a reutizar, ya que me aseguro de eliminarlas, solo cuando la aplicación se va ha cerrar..

1. ¿Entonces las estoy liberando bien?
2. Puesto que no las libero hasta que la aplicación se cierra, ¿tendría que proceder a liberarlas cuando sucede una Excepción Grave?
3. Es que en un Libro que tengo de C++(NO Builder), dice que la memoria de los array bimensionales se pueden liberar así: delete [] Objeto;
aunque estos sean bimensionales. He intentando hacer esto para no tener que recorrer todo el bucle for(){} eliminando los TBitmap pero me dá error en ejecución, así que estoy un poco confuso.

Según el enlace que has puesto, ahí dice que por seguridad cuando se elimna un puntero se le puede asignar el valor CERO, para que en caso de en otra parte del codigo se vuleve a eliminar ese puntero no dé ERROR. Eso ya lo sabía, gracias a que me lo digiste en otro post.

La preguntas reales son 2:
1. ¿Estoy liberando bien la memoria asignada con el oprador new?
2. ¿Por qué no puede liberarla así? delete [] BMP; sin utilizar el bucle, claro.

GRACIAS.
_________________
Muchos hombres no se equivocan jamás porque no se proponen nada razonable.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor
Mensaje    Asunto: Responder citando

JesúsGandia escribió:
1. ¿Entonces las estoy liberando bien?

Si.

JesúsGandia escribió:
Puesto que no las libero hasta que la aplicación se cierra, ¿tendría que proceder a liberarlas cuando sucede una Excepción Grave?

Yo las liberaría en el destructor.. así hay menos peligro si ocurre alguna excepción no controlada..

JesúsGandia escribió:
Es que en un Libro que tengo de C++(NO Builder), dice que la memoria de los array bimensionales se pueden liberar así: delete [] Objeto;
JesúsGandia escribió:
2. ¿Por qué no puede liberarla así? delete [] BMP; sin utilizar el bucle, claro.

En tu caso tienes que usar "delete" a secas. Usarías "delete[]" en caso de que al reservar la memoria uses "...new TIPO[...]", como en el siguiente ejemplo: (creando las dimensiones de tu array también dinámicamente)
Código:
Graphics::TBitmap* **BMP = new Graphics::TBitmap* *[45];
for (int i = 0; i < 45; i++) BMP[i] = new Graphics::TBitmap*[120];

    for(short int g = 0; g < 45; g++)
        for(short int a = 0; a < 120; a++)
            BMP[g][a] = new Graphics::TBitmap;

    //....

    for(short int g = 0; g < 45; g++)
        for(short int a = 0; a < 120; a++)
            delete BMP[g][a];

for (int i = 0; i < 45; i++) delete[] BMP[i];
delete[] BMP;

(solo como ejemplo, ya que si necesitaras crear las dimensiones dinámicamente creo que quedaría un poco más claro el código usando la plantilla "vector" de la librería estándar de C++)
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

_Leo Escribio escribió:

Yo las liberaría en el destructor.. así hay menos peligro si ocurre alguna excepción no controlada.


Nunca he utizado el desctructor de un formulario, por favor ¿podrías ponerme un pequeño ejemplo?
_________________
Muchos hombres no se equivocan jamás porque no se proponen nada razonable.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor
Mensaje    Asunto: Responder citando

JesúsGandia escribió:
Nunca he utizado el desctructor de un formulario, por favor ¿podrías ponerme un pequeño ejemplo?

El Form no es más que una clase como cualquier otra..

- En la cabecera:
Código:
public:      // User declarations

   __fastcall TfrmVentas(TComponent* Owner);
   __fastcall ~TfrmVentas();  // <----

- En el .cpp:
Código:
__fastcall TfrmVentas::~TfrmVentas()
{
    //...
}
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Gracias _Leo.
_________________
Muchos hombres no se equivocan jamás porque no se proponen nada razonable.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.