| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Mar 25 May, 2010 1:23 am Asunto: vectores bimensionales dinamicos. ¿Ayuda por favor? |
|
|
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 |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Mar 25 May, 2010 2:22 am Asunto: |
|
|
| 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 |
|
 |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Mar 25 May, 2010 3:26 am Asunto: |
|
|
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 |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Mar 25 May, 2010 4:17 am Asunto: |
|
|
| 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 |
|
 |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Mar 25 May, 2010 12:34 pm Asunto: |
|
|
| _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 |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Mar 25 May, 2010 2:17 pm Asunto: |
|
|
| 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 |
|
 |
JesúsGandia Master


Registrado: 17 Jul 2004Mensajes: 403Ubicación: Gandia, Valencia
|
Publicado: Mar 25 May, 2010 3:50 pm Asunto: |
|
|
Gracias _Leo. _________________ Muchos hombres no se equivocan jamás porque no se proponen nada razonable. |
|
| Volver arriba |
|
 |
|