FPC - wasted memory - solution ? 
Author Message
 FPC - wasted memory - solution ?

It was claimed that using classes one cannot automatially
free memory allocated to temporaries in expressions. I think
that while not nice there is a solution. One needs to declare
two classes: permanent and a temporary one. Both should be
identical, except for their type. All overloaded operators
generate temporary results. On assignment temporary result
is converted to a permanent one. In fact one need four copies
of each (binary) operator, depending on if arguments are permanent or
temporary. Operator is responsible for freeing all its temporary
arguments. If one wants to have functions one have to define as
many copies as needed (for 10 arguments 1024 copies :( ).
The code below ilustrates the idea:

type
    myclass = class
                data : integer
                end;

    Tmpclass = class
                data : integer
                end;

Operator := (x : Tmpclass) y : myclass ;
begin
        y := myclass.create;
        y.data := x.data;
        writeln('assignment, freeing x')
end;

Operator + (x , y : myclass) z : Tmpclass;
begin
        writeln('adding');
        z := Tmpclass.create;
        z.data := x.data + y.data
end;

Operator + (x : Tmpclass; y : myclass) z : Tmpclass;
begin
        z := Tmpclass.create;
        z.data := x.data + y.data ;
        writeln('adding, freeing x')
end;

Operator + (x : myclass; y : Tmpclass) z : Tmpclass;
begin
        z := Tmpclass.create;
        z.data := x.data + y.data ;
        writeln('adding, freeing y')
end;

Operator + (x, y : Tmpclass) z : Tmpclass;
begin
        z := Tmpclass.create;
        z.data := x.data + y.data ;
        writeln('adding, freeing x, freeing y')
end;

var x, y, z : myclass;

begin
  writeln('begin');
  x := myclass.create;
  writeln('x created');
  y := myclass.create;
  writeln('y created');
  z := y;
  y.data := 5;
  x.data := 3;
  writeln('before addition');
  x := z + ((x + y) + z) ;
  writeln('after addition');
  writeln(x.data)
end.

--
                              Waldek Hebisch



Sun, 18 Dec 2005 22:00:03 GMT  
 FPC - wasted memory - solution ?

Quote:
> It was claimed that using classes one cannot automatially
> free memory allocated to temporaries in expressions. I think
> that while not nice there is a solution. One needs to declare
> two classes: permanent and a temporary one. Both should be
> identical, except for their type. All overloaded operators
> generate temporary results. On assignment temporary result
> is converted to a permanent one. In fact one need four copies
> of each (binary) operator, depending on if arguments are permanent or
> temporary. Operator is responsible for freeing all its temporary
> arguments. If one wants to have functions one have to define as
> many copies as needed (for 10 arguments 1024 copies :( ).
> The code below ilustrates the idea:

> type
>     myclass = class
>                 data : integer
>                 end;

>     Tmpclass = class
>                 data : integer
>                 end;

> Operator := (x : Tmpclass) y : myclass ;
> begin
>         y := myclass.create;
>         y.data := x.data;
>         writeln('assignment, freeing x')
> end;

> Operator + (x , y : myclass) z : Tmpclass;
> begin
>         writeln('adding');
>         z := Tmpclass.create;
>         z.data := x.data + y.data
> end;

> Operator + (x : Tmpclass; y : myclass) z : Tmpclass;
> begin
>         z := Tmpclass.create;
>         z.data := x.data + y.data ;
>         writeln('adding, freeing x')
> end;

> Operator + (x : myclass; y : Tmpclass) z : Tmpclass;
> begin
>         z := Tmpclass.create;
>         z.data := x.data + y.data ;
>         writeln('adding, freeing y')
> end;

> Operator + (x, y : Tmpclass) z : Tmpclass;
> begin
>         z := Tmpclass.create;
>         z.data := x.data + y.data ;
>         writeln('adding, freeing x, freeing y')
> end;

> var x, y, z : myclass;

> begin
>   writeln('begin');
>   x := myclass.create;
>   writeln('x created');
>   y := myclass.create;
>   writeln('y created');
>   z := y;
>   y.data := 5;
>   x.data := 3;
>   writeln('before addition');
>   x := z + ((x + y) + z) ;
>   writeln('after addition');
>   writeln(x.data)
> end.

it works {except that you forgot to call Destroy in operators ;-)},
but here

x := z + ((x + y) + z)

you assign a new value to already created variable, loosing memory allocated
for the previous x.

t:=z+((x+y)+z)

would work fine.

--
Azarien



Mon, 19 Dec 2005 02:54:05 GMT  
 FPC - wasted memory - solution ?
Good extension of my old idea(except 1024).

My new idea,and avoid of 2^n problem:

Type Tmaybetemp=class{we may use it for different types}
 {istemp:boolean;}{we may use it instead of "is " operator}
 constructor create;{set istemp (if we have istemp) to false}
 procedure DestroyIfTemp;virtual;{destroy if istemp true(if we have
istemp)}
end;

Type tMyClassParent= class(tmaybetemp){We may use only this class if
we don't want to overload ":"}
 data : integer;
end;

Type Ttempclass = class(TmyclassParent)
 { constructor create;}{set istemp to true}
 {if we work without boolean "istemp"}
 procedure DestroyIfTemp;override;{destroy }
end;

Type Tmyclass = class(TmyclassParent)
 {constructor create;}{set istemp to false}
 {if we work without boolean "istemp"}
 procedure DestroyIfTemp;override;{does not destroy}
end;

Operator +(x,y:tmyclassparent):ttempclass;{just only one operator}
begin
 result:=ttempclass.create;{create temp}
 result.data:=x.data+y.data;
 x.destroyiftemp;
 y.destroyiftemp;{even if we have 10 operands..}
end;
function copy(a:tmyclassparent):tmyclass;{you may use it as ":=",if
you want.I don't like to overload ":="}
begin
 result:=tmyclass.create;
 result.data:=a.data;
 a.destroyiftemp;
end;

a:=copy(b*(c+d));{Uniform "something:=copy(reallyANYexpression)",we
may not worry about "it's temp or reference?" }

if we can't destroy self in normal proc(not destructor).,we can use
destroy out of class(like destroyiftemp(someclass) ,bool istemp is
specially for it)

Personally i think it's better to use my first idea with
 a.newinstance*(b.newinstance+c.newinstance)

form.
If you can't overload ":=" in this case(i don't checked),
use "copy(a*(b+c))" -it's better than overloading ewen if you can
overload ":="

oops,with bool istemp we may not copy temp in "copy"...

Dmytry.

p.s. it's not my primary job.But,maybe,i will use it....(i will use
only pointers to records,of course!).Also,i'm interested in matrixes.

We may not more use lists and may not fill program with
"destroyalltemps"

Quote:

> It was claimed that using classes one cannot automatially
> free memory allocated to temporaries in expressions. I think
> that while not nice there is a solution. One needs to declare
> two classes: permanent and a temporary one. Both should be
> identical, except for their type. All overloaded operators
> generate temporary results. On assignment temporary result
> is converted to a permanent one. In fact one need four copies
> of each (binary) operator, depending on if arguments are permanent or
> temporary. Operator is responsible for freeing all its temporary
> arguments. If one wants to have functions one have to define as
> many copies as needed (for 10 arguments 1024 copies :( ).
> The code below ilustrates the idea:

> type
>     myclass = class
>                 data : integer
>                 end;

>     Tmpclass = class
>                 data : integer
>                 end;

> Operator := (x : Tmpclass) y : myclass ;
> begin
>         y := myclass.create;
>         y.data := x.data;
>         writeln('assignment, freeing x')
> end;

> Operator + (x , y : myclass) z : Tmpclass;
> begin
>         writeln('adding');
>         z := Tmpclass.create;
>         z.data := x.data + y.data
> end;

> Operator + (x : Tmpclass; y : myclass) z : Tmpclass;
> begin
>         z := Tmpclass.create;
>         z.data := x.data + y.data ;
>         writeln('adding, freeing x')
> end;

> Operator + (x : myclass; y : Tmpclass) z : Tmpclass;
> begin
>         z := Tmpclass.create;
>         z.data := x.data + y.data ;
>         writeln('adding, freeing y')
> end;

> Operator + (x, y : Tmpclass) z : Tmpclass;
> begin
>         z := Tmpclass.create;
>         z.data := x.data + y.data ;
>         writeln('adding, freeing x, freeing y')
> end;

> var x, y, z : myclass;

> begin
>   writeln('begin');
>   x := myclass.create;
>   writeln('x created');
>   y := myclass.create;
>   writeln('y created');
>   z := y;
>   y.data := 5;
>   x.data := 3;
>   writeln('before addition');
>   x := z + ((x + y) + z) ;
>   writeln('after addition');
>   writeln(x.data)
> end.



Mon, 19 Dec 2005 03:23:18 GMT  
 FPC - wasted memory - solution ?

Quote:

> It was claimed that using classes one cannot automatially
> free memory allocated to temporaries in expressions. I think
> that while not nice there is a solution. One needs to declare
> two classes: permanent and a temporary one. Both should be
> identical, except for their type. All overloaded operators
> generate temporary results. On assignment temporary result
> is converted to a permanent one. In fact one need four copies
> of each (binary) operator, depending on if arguments are permanent or
> temporary. Operator is responsible for freeing all its temporary
> arguments. If one wants to have functions one have to define as
> many copies as needed (for 10 arguments 1024 copies :( ).
> The code below ilustrates the idea:

This is a good solution except for

Quote:
> Operator := (x : Tmpclass) y : myclass ;
> begin
>         y := myclass.create;
>         y.data := x.data;
>         writeln('assignment, freeing x')
> end;

where you shouldn't call the creator for y. The := operator should be
part of your myclass object and therefore always referring to a
previously created object.
In your way you will leak memory when you first create x

Quote:
> x := myclass.create;
> writeln('x created');

then assign something to it, using the := operator

Quote:
> x := z + ((x + y) + z) ;

This will lose the original pointer, giving you no reference to some
allocated memory.

But besides that the solution is valid. And ten arguments is not
necesarily 1024 copies of the temporary object, a+b+c+d+e+f+g+... will
only have one temporary object at all times. The real challenge comes
when using paranthesis so the calculation will have to store several
sub-results (a+b)*(c+d)...

/Nic



Mon, 19 Dec 2005 14:30:50 GMT  
 FPC - wasted memory - solution ?

Quote:
> But besides that the solution is valid. And ten arguments is not
> necesarily 1024 copies of the temporary object, a+b+c+d+e+f+g+... will
> only have one temporary object at all times. The real challenge comes
> when using paranthesis so the calculation will have to store several
> sub-results (a+b)*(c+d)...

He meant 1024 versions of
function do_something(a,b,c,d,e,f,g,h,i,j:<myclass|tmpclass>):tmpclass;

--
Azarien

[delete the letter v from my e-mail address]



Mon, 19 Dec 2005 19:01:46 GMT  
 FPC - wasted memory - solution ?

Quote:

> > But besides that the solution is valid. And ten arguments is not
> > necesarily 1024 copies of the temporary object, a+b+c+d+e+f+g+... will
> > only have one temporary object at all times. The real challenge comes
> > when using paranthesis so the calculation will have to store several
> > sub-results (a+b)*(c+d)...

> He meant 1024 versions of
> function do_something(a,b,c,d,e,f,g,h,i,j:<myclass|tmpclass>):tmpclass;

Ah, I see - but there is no use for that when overloading operators... Is there?

Nic



Tue, 20 Dec 2005 14:04:11 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. FPC - wasted memory...

2. more than 640K of memory -- portable solution

3. Need solution for memory leak problem with dynamic SQL

4. FPC Win32 memory mapped files for IPC

5. FPC Win32 memory mapped files for IPC

6. FPC, TMT, and memory usage.

7. FPC: ^longint type, memory question

8. Paradox, (16 bit BDE) and wasted space - HELP

9. FPC:problem with printing from fpc programs

10. FPC: translate execvp from c to FPC

11. Pascal a waste of time?

12. New Strategy Game: Blasted Wastes

 

 
Powered by phpBB® Forum Software