Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Liberar Objetos ¿Cómo resolver esto? (https://www.clubdelphi.com/foros/showthread.php?t=64826)

josuk 21-04-2009 22:43:40

Liberar Objetos ¿Cómo resolver esto?
 
La creación de objetos se realiza sin problemas, en particular se trata de un objeto ”Casa” que contiene un array dinámico de objetos “Habitacion”.
Pero el problema es a la hora de liberarlos, dando error de violación de memoria.

¿Qué estoy haciendo mal?
¿Cómo debería hacerlo?

Si alguien lo consigue por favor decidme cómo!

Os pongo el código a continuación. Gracias compañeros.

...
Type
THabitacion = class (TObject)
Descripcion: string;
end;

TCasa = class (TObject)
Habitacion: array of THabitacion;
end;

var
Casa: TCasa;

implementation

procedure TForm1.BotonCrearClick (Sender: TObject);
begin
Casa:= TCasa.Create;
SetLength(Casa.Habitacion,1);
Casa.Habitacion[1]:=THabitacion.Create;
Casa.Habitacion[1].Descripcion:='Dormitorio';
end;

procedure TForm1.BotonLiberarrClick (Sender: TObject);
begin
Casa.Habitacion[1].Free;
Finalize(Casa.Habitacion);
Casa.Free;
end;
...

roman 21-04-2009 22:49:26

De entrada recuerda que los arreglos dinámicos comienzan en cero, por lo que si asignas memoria para un sólo elemento:

Código Delphi [-]
SetLength(Casa.Habitacion,1);

entonces no es válido usar Casa.Habitacion[1]. Tendría que ser Casa.Habitacion[0].

Otra cosa: Por favor usa las etiquetas [delphi] para publicar código:


[delphi]

Aquí tu código

[/delphi]


// Saludos

josuk 22-04-2009 01:28:15

vaya, vaya
 
Muchas gracias Román, qué velocidad en responder!... y qué ridículo me siento:o ... efectivamente estaba utilizando un índice fuera de rango... y claro, por defecto Delphi no avisa de estos "detalles"...

El código que tengo entre manos realmente es bastante más complejo y cada objeto de los que he llamado Habitacion tienen a su vez varios arrays de objetos anidados y me volví loco buscando el error en algo menos "obvio" que un índice... bueno, no tengo excusa.

Entendido lo de las etiquetas

Gracias de nuevo!

PD.: Enhorabuena por este foro que ya había visitado en alguna ocasión y en el que por fín participo... espero ser útil en otra ocasión.

gerardus 17-11-2009 10:53:36

Hola Josuk,

Tienes la opción de usar listas de objetos en vez de arrays:

Código Delphi [-]
  uses contnrs; // requerido por TObjectList

  TCasa = class (TObject)
  private
    FHabitaciones: TObjectlist;
    function GetHabitaciones(Index: integer): Thabitacion;
    function GetNumerohabitaciones: integer;
  public
    constructor create;
    destructor destroy override;
    function AddHabitacion : THabitacion;
    property Habitaciones[Index: integer]: Thabitacion read GetHabitaciones;
    property Numerohabitaciones: integer read GetNumerohabitaciones;
  end;



function TCasa.AddHabitacion: THabitacion;
begin
  Result := THabitacion.Create;
  FHabitaciones.Add(Result);
end;

constructor TCasa.create;
begin
  inherited Create;
  FHabitaciones := TObjectList.Create(True); // True destruye los objetos de la lista al ser destruido
end;

destructor TCasa.destroy;
begin
  FHabitaciones.Free;
  inherited;
end;

function TCasa.GetHabitaciones(Index: integer): Thabitacion;
begin
  Result := THabitacion(FHabitaciones[Index]);
end;

function TCasa.getNumerohabitaciones: integer;
begin
  Result := FHabitaciones.Count;
end;

Cordialmente,

Gerard.

Lepe 17-11-2009 15:00:53

Ya puestos... ¿por qué no heredar de TobjectList?
Código Delphi [-]
unit Unit1;

interface

uses Contnrs;
type THabitacion = class(TObject)
  public
    id :integer;
end;


type THabitacionList  = class(TObjectList)
  private
    function GetItem(Index: Integer): THabitacion;
    procedure SetItem(Index: Integer; const Value: THabitacion);
  public
    function Extract(Item: THabitacion): THabitacion;
    function First: THabitacion;
    function Last:THabitacion;
    property Items[Index: Integer]: THabitacion read GetItem write SetItem; default;
  end;
  


implementation


{ THabitacionList }

function THabitacionList.Extract(Item: THabitacion): THabitacion;
begin
  result := THabitacion(inherited Extract(Item));
end;

function THabitacionList.First: THabitacion;
begin
  result := THabitacion(inherited First);
end;

function THabitacionList.GetItem(Index: Integer): THabitacion;
begin
  result:= THabitacion(inherited GetItem(Index));
end;

function THabitacionList.Last: THabitacion;
begin
  result := THabitacion(inherited Last);
end;

procedure THabitacionList.SetItem(Index: Integer; const Value: THabitacion);
begin
  inherited SetItem(Index, Value);
end;

end.

No es necesario todo el código... pero a mí me gusta así.

PD: Yo uso un experto de cnpacks que hice, sólo escribo "Habitacion" un clic de ratón... y se escribe todo eso.

gerardus 17-11-2009 15:40:50

Cita:

Empezado por Lepe (Mensaje 346754)
Ya puestos... ¿por qué no heredar de TobjectList?

Es perfectamente valido.

Cita:

Empezado por Lepe (Mensaje 346754)
PD: Yo uso un experto de cnpacks que hice, sólo escribo "Habitacion" un clic de ratón... y se escribe todo eso.

Yo uso el ModelMaker Code Explorer, que tambien permite usar plantillas de clases predefinidas (Entre muchas otras cosas). Tendré que echar un vistazo al cnpack, a ver que tal.

Cordialmente,

Gerard

rgstuamigo 17-11-2009 15:44:21

Bueno.tambien si esta usando Delphi 2009 o superior tambien podria usar los generico especificando que tipo de dato introducira en la lista y sin codificar casi nada.;)
Saludos...:)

josuk 17-11-2009 15:47:28

Hola compañeros,

Gerardus, buena opción la que propones, ciertamente le da bastante formalidad y elegancia al planteamiento.

Y bueno Lepe, nada como optimizar, tanto la idea como el código.

Gracias por vuestro tiempo y punto de vista.


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

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