Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Invalid Pointer Operation con Free y Assigned (https://www.clubdelphi.com/foros/showthread.php?t=25894)

adlfv 06-10-2005 19:28:10

Invalid Pointer Operation con Free y Assigned
 
Hola a todos, yo creo que tengo el mismo error... y me estoy volviendo LOOOOCO y no logro resolverlo. Seguramente sea una tontería, pero es que NO LO LOGRO.

Explico mi caso.

Estoy haciendo el modelo de negocios de un hotel, el cual explico brevemente:
- Clase THabitaciones (hereda de TComponent), que es básicamente una lista con componentes THabitacion (o TBaseHabitacion).
- Clase THabitacion (hereda de TComponent), representa una habitación como tal. Está formada basicamente por dos partes, Un componente GUI: TBaseGUI y un objeto Info: TBaseInfo.
- Clase TBaseGUI (hereda de TComponent), es el tope de una jerarquia para la representación gráfica de las habitaciones.
- Clase TBaseInfo (hereda de TObject), es el tope de una jerarquia para la información de las habitaciones. Va variando según el tipo en tiempo de ejecución.


En el form principal hago lo siguiente en el evento OnClose:
Código:

 
  ...
  TiposHabitaciones.Free;
  Habitaciones.Free;


La idea es:
1.- Destruir Habitaciones: THabitaciones (cuando creo una Habitacion: THabitacion hereda de TComponent y el Owner es Habitaciones, con lo cual automáticamente se liberan todas las THabitacion cuyo Owner sea Habitaciones).
2.- Cuando se destruye una Habitacion: THabitacion, básicamente tengo que destruir la Info pues hereda de TBaseInfo que a su vez hereda de TObject. GUI no hay que destruirlo, pues se autodestruye porque tiene como Owner la Habitacion
3.- Cuando se destruye un GUI: TGUIHab, debo liberar el bitmap.


A continuación pondré los métodos de destrucción de las clases en ese orden:


1.- Destrucción de Habitaciones: (en realidad no hago nada salvo Lista.Clear y Lista.Free).

Código:

  Debug('THabitaciones.Destroy: ComponentCount:' + IntToStr(ComponentCount));
  Debug('THabitaciones.Destroy: FLista.Count:' + IntToStr(FLista.Count));
 
  for i := 0 to FLista.Count -1 do
  begin
    H := ItemsByPos[i];
    if Assigned(H) then
    begin
          if H.Owner <> nil then
            Debug(H.Caption + ' Owned by: ' + TComponent(H.Owner).Name);
  //        H.FreeInfo;
  //        H.FreeGUI;
  //        H.Free;
    end;
  //  Lista.Objects[i].Free;
  end;
 
  Lista.Clear;
  Debug('THabitaciones.Destroy: ComponentCount:' + IntToStr(ComponentCount));
 
  Lista.Free;
  Debug('La lista interna ha sido liberada');
  inherited Destroy;


2.- Destrucción de Habitacion: Tengo qeu destruir sólo la Info (pero está comentado, pues sospecho que me da error en el Assigned(Info)) pues el GUI tiene como Owner la Habitación y se destruirá solo.


Código:

  Debug(Caption + ': THabitacion.Destroy: ComponentCount:' + IntToStr(ComponentCount));
 
  if Assigned(Info) then
  begin
    Debug(Caption + ': TBaseHab.Destroy - assignado. Tipo:' + Info.ClassName);
  //  FreeInfo;
  //  FreeGUI;
  end
  else
    Debug(Caption + ': TBaseHab.Destroy - no assignado');
 
  Debug(Caption + ': THabitacion.Destroy: ComponentCount:' + IntToStr(ComponentCount));
  inherited Destroy


3.- Destrucción de GUI.


Código:

 
  if Assigned(Owner) then
  begin
    Debug('Liberando bitmap de GUI de la habitacion: ' + TComponent(Owner).Name);
    FreeResources;
  end;
 
  Debug('TGUIHabIcon: ComponentCount=' + IntToStr(ComponentCount));
 
  //TODO: LLamar al heredado?


La destrucción de Info no hace nada salvo llamar al heredado.


Al cerrar la aplicación obtengo un precioso mensaje :mad:: "Invalid pointer operation." (EInvalidPointer)

Alguien me puede echar una mano con esto, por favor.

Le estaré muy agradecido, pues no logro detectar el error... Creo que falla en el if Assigned(Info) de THabitacion.Destroy, pero no estoy seguro y además no sé cómo resolverlo.

Muchas gracias de antemano y disculpen por el mensaje tan largo.

PD: A continuación adjunto la pila, por si pueda ser útil.

------------------------------------------------------------------------------------------------
|Address |Module |Unit |Class |Procedure/Method |Line|
------------------------------------------------------------------------------------------------
|40003364|rtl90.bpl |System.pas | |Error | |
|400031AB|rtl90.bpl |System.pas | |_FreeMem | |
|40003198|rtl90.bpl |System.pas | |_FreeMem | |
|40005DBE|rtl90.bpl |System.pas | |_ClassDestroy | |
|40005DBC|rtl90.bpl |System.pas | |_ClassDestroy | |
|01658F68|CoreClassHab.bpl|UCGUIHab.pas |TGUIIcon |Destroy |127 |
|4003D718|rtl90.bpl |Classes.pas |TComponent |DestroyComponents | |
|4003D518|rtl90.bpl |Classes.pas | |TComponent | |
|01654CD6|CoreClassHab.bpl|UCHabitaciones.pas|TBaseHabitacion|Destroy |195 |
|77D2F3DE|user32.dll | | |SendMessageA | |
|77D2F39A|user32.dll | | |SendMessageA | |
|0067455A|vcl90.bpl |Comctrls.pas |TCustomListView|Scroll | |
|40006B58|rtl90.bpl |System.pas | |_LStrArrayClr | |
|003F203E|CoreLog.bpl |ULog.pas | |Log |64 |
|4003D718|rtl90.bpl |Classes.pas |TComponent |DestroyComponents | |
|4003D518|rtl90.bpl |Classes.pas | |TComponent | |
|01655442|CoreClassHab.bpl|UCHabitaciones.pas|THabitaciones |Destroy |429 |
|400059D4|rtl90.bpl |System.pas |TObject |Free | |
|400059CC|rtl90.bpl |System.pas |TObject |Free | |
|01654433|CoreClassHab.bpl|UClassObjects.pas | |CoreClassHabDestroy |30 |
|01654424|CoreClassHab.bpl|UClassObjects.pas | |CoreClassHabDestroy |29 |
|01715794|CoreMain.bpl |UPrincipal.pas |TFrmPrincipal |FormClose |357 |

dec 06-10-2005 19:37:42

Hola,

A bote pronto se me ocurre (seguramente sea una obviedad o ya lo estés haciendo) que pongas algún que otro punto de ruptura, por ejemplo, al entrar en los destructores correspondientes. De ese modo podrás averiguar tal vez cuál sea la causa del problema. Espero que decir esto no resulte del todo fatuo.

adlfv 06-10-2005 21:17:02

Hola.

Gracias por contestar.

La verdad no he podido hacer eso porque Delphi 2005 no me permite depurar, no se si es que tenga muchos componentes instalados (que tampoco tengo tantos) o que sea muy grande la aplicación, pero el caso es que cuando le doy a ejecutar desde el ide, se queda colgado :mad:.

Alguna otra idea o sugerencia?

Gracias

dec 07-10-2005 00:17:06

Hola,


Cita:

Empezado por adflv
La verdad no he podido hacer eso porque Delphi 2005 no me permite depurar, no se si es que tenga muchos componentes instalados (que tampoco tengo tantos) o que sea muy grande la aplicación, pero el caso es que cuando le doy a ejecutar desde el ide, se queda colgado :mad:.

Lo cierto es que no veo relación en que tengas muchos o pocos componentes instalados (como no sea que alguno de ellos estuviera influenciando en ello directamente) o el que tu aplicación sea "muy grande" para que no te funcione el "debugger" interno de Delphi. Lo que sí creo es que solucionar el tema del "debugger" podrá ayudarte no poco en el problema que has planteado y más allá en el trabajo con Delphi.


Cita:

Empezado por adflv
Alguna otra idea o sugerencia?

Pues que trates de solucionar primeramente el problema del "debugger" interno de Delphi. Parecerá una respuesta facilona, esto es, parecerá olvidarse del problema principal, pero, es que creo que el "debugger" sería de una tremenda ayuda para solucionar dicho problema. Mientras arreglas el "debugger" interno, tal vez no te venga mal utilizar uno "externo", o bien algún componente en concreto: en este reciente Hilo se mencionan algunas posibilidades que tal vez puedas aprovechar.


La franja horaria es GMT +2. Ahora son las 05:05:35.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi