Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 203
  • Last Modified:

Problem freeing memory

Hello.
I have problems freeing resources on my application. I don't know if I'm
doing the things well, so please tell me where could be my mistake.
I have some pointers (structures) that I store on a Tlist. Some of that
structures have lists that store more pointers.
So I have something like this:

  TAAmostra=^TAmostra;
  TAmostra = record
    NumAmostra:integer;
    N:integer;
    hora:TDateTime;
    ListaPesagens:TList;
    ...
    prod:TPProduto;
    ...
  end;

  TPPesagem=^TPesagem;
  TPesagem = record
    N:integer;
    MBRUTA:single;
    Tara:single;
    MLiquida:single;
    VLiquido:single;
  end;

In this situation, the structure TAAmostra has a list (ListaPesagens) that
is going to store the TPPesagem structure.
So then I have this list:

listaAmostras:Tlist;

and the variables

amo:TAAmostra;
pes:TPPesagem

I then create a new dynamic variable and place it in the TList:

        new(amo);
        amo.numamostra:=b;
        ...
        for a:=1 to 5 do
        begin
            new(pes);
            pes.n:=a;
            ...
        end;

        amo.listapesagens.add(pes);

        listaamostras.add(amo);

So, in this way I can easily access the info I want like this:

procedure search(amo:TAAmostra);
var
    a:integer;
    pes:TPPesagem;
begin
    for a:=0 to amo.listapesagens.count-1 do
    begin
        pes:=amo.listapesagens.items[a];
        ...
        ...
    end;
end;

So, this is how I manipulate the structures.
To free them I do something like this:

        for a:=0 to listaAmostras.count-1 do
        begin
            amo:=listaAmostras.Items[a];
            for b:=0 to amo.ListaPesagens.count-1 do
            begin
                pes:=amo.ListaPesagens.items[b];
                dispose(pes);
            end;
            amo.ListaPesagens.Clear;
            amo.ListaPesagens.capacity:=0;
            dispose(amo);
        end;
        listaamostras.clear;
        listaamostras.capacity:=0;

My problem is this: I have a procedure that "refreshes" the data in the
structures. To do so, I want to free the memory allocated to the TAAmostra
structure and then create a new one with the new values. Well, it seems it
isn't freeing the memory, because if I run that procedure 20 times in a row
I get an EoutofMemory exception. But if I'm freeing the memory and then
allocating space for exactly the same data, the occupied memory should
always be the same!!!
I know this description is a little long, but this is very important. My
deadline is next wednesday and I must have this problem solved. Anyone can
help?
Thanks for your time.
Best Regards

Goncalo Martins


0
reina
Asked:
reina
2 Solutions
 
God_AresCommented:
This is just a little test case wit a data structure simmelair to yours...

it's just a form with one button...

look in to it  and i'm shure you'll find your awnser.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


  PTHolder = ^Tholder; //Start's with a 'P' because it's a pointer
  THolder = record
              random_number : Integer;
              some_string : String;
              A_List : Tlist;
            end;

  PTSubData = ^TSubData;
  TSubData = record
                jadajada:Integer;
                bla : string;
             end;


var
  Form1: TForm1;

implementation

{$R *.DFM}

var List_of_holders : TList;

procedure TForm1.Button1Click(Sender: TObject);
var Holder : PTHolder;
    Sub:PTSubData;
    j,i:Integer;
    before,after : Integer;

begin
  before := GetHeapStatus.TotalAllocated;
  List_of_holders := Tlist.Create;

  For j:=1 to 10 Do  //create some data
  Begin

    new(Holder); //make a new holder
    Holder^.random_number := Random(1000);
    Holder^.some_string := 'BlaBla';
    Holder^.A_List := Tlist.Create; //create a list
    For i:=1 to 5 do
    Begin
      new(Sub); //create new sub data
      Sub^.jadajada := (j*10)+i;
      Sub^.bla := 'ad';

      Holder^.A_List.Add(sub); //store in holder list.
    End;

    List_of_holders.Add(Holder); //store holder in holders list
  end;

  For j:=0 to List_of_holders.Count-1 Do  //now we'll free it all.
  Begin
    Holder := List_of_holders.Items[j];

    For i:=0 to Holder^.A_List.Count-1 Do
    Begin
      Sub := Holder^.A_List.Items[i];
      //ShowMessage(IntToStr(Sub^.jadajada));  //if you uncomment't this line a
                                               //memory leak will occur.
                                               //due to showmessage.
      Dispose(Sub);  // free
    End;
    Holder^.A_List.free; //Free's memmory for this object.

    Dispose(Holder); //free's this one.
  End;

  List_of_holders.free; //don't forget to free this one too.

  after := GetHeapStatus.TotalAllocated;

  if after = before then showmessage('it''s ok') else showmessage(IntToStr(Abs(before-after)) + ' bytes lost' );




end;

end.
0
 
ITugayCommented:
Hi reina,

there is another way to keep list of records. Declare your record as class of TObject and use TObjectList. It able to be responsible for automatic free objects inside. Take a look at Delphi's help. It is really easy and comforatble list.

-----
Igor.

   
0
 
pnh73Commented:
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Split Points between ITugay and God_Ares

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Paul (pnh73)
EE Cleanup Volunteer
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now