FPC - wasted memory... 
Author Message
 FPC - wasted memory...

Suppose we have a class type with overloaded operators:

var a,b,c,d:someclass;

and then

c:=a+b;    // OK

but:

d:=a*b+c;

works fine too, but some memory gets wasted - the program allocates a class
variable with a*b result which is not destroyed after resolving the whole
expression, and there's not any reference to that variable. Is there any way
to solve this problem?

of course one could do

temp:=a*b;
d:=temp+c;
temp.destroy;

but this is NOT the solution ;-)

--
Azarien



Fri, 09 Dec 2005 07:35:55 GMT  
 FPC - wasted memory...

Quote:

> Suppose we have a class type with overloaded operators:

Dynamic types are not possible for now. One could try to use TP Object type.

Quote:
> but this is NOT the solution ;-)

There is none, except to use static objects.


Sat, 10 Dec 2005 02:23:23 GMT  
 FPC - wasted memory...

Quote:
> > Suppose we have a class type with overloaded operators:

> Dynamic types are not possible for now. One could try to use TP Object
type.

> > but this is NOT the solution ;-)

> There is none, except to use static objects.

But it still doesn't help me - my class (or object) allocates some memory
(size known at runtime) in constructor, which is freed in destructor.

I'll try to store this data in ansistrings which seem to be more or less
dynamically allocated...

--
Azarien

delete the letter v from my e-mail address



Sat, 10 Dec 2005 06:37:52 GMT  
 FPC - wasted memory...

Quote:

> Suppose we have a class type with overloaded operators:

> var a,b,c,d:someclass;

> and then

> c:=a+b;    // OK

> but:

> d:=a*b+c;

> works fine too, but some memory gets wasted - the program allocates a class
> variable with a*b result which is not destroyed after resolving the whole
> expression, and there's not any reference to that variable. Is there any way
> to solve this problem?

> of course one could do

> temp:=a*b;
> d:=temp+c;
> temp.destroy;

> but this is NOT the solution ;-)

If it works like this, you got a someclass.Create() somewhere in your
operator overload code. Bad karma, as

a:=someclass.Create();
b:=someclass.Create();
c:=someclass.Create();
... code ...
a:=b+c;

will lose the original pointer to a, thus causing yet another memory
leak.
I see no good solution to this. What I do when I do c is to have a
local object of the return type, assign values to this, and return a
pointer to the object _even though its free'd before I can use it_ -
the data I need is ofcourse still where I left them ;) I know this is
a bad solution, but imo preferable to a memory leak.

Anyone got a better idea so I can go back home and change my old code
tonight? :p

/Nic



Sat, 10 Dec 2005 19:57:49 GMT  
 FPC - wasted memory...

Quote:

>> > Suppose we have a class type with overloaded operators:

>> Dynamic types are not possible for now. One could try to use TP Object
> type.

>> > but this is NOT the solution ;-)

>> There is none, except to use static objects.

> But it still doesn't help me - my class (or object) allocates some memory
> (size known at runtime) in constructor, which is freed in destructor.

Let me rephrase: Operator overloading and dynamic types (including classes)
are not possible.

Quote:
> I'll try to store this data in ansistrings which seem to be more or less
> dynamically allocated...

Yes, but they already have operators defined.


Sun, 11 Dec 2005 18:13:34 GMT  
 FPC - wasted memory...

Quote:

> Let me rephrase: Operator overloading and dynamic types (including classes)
> are not possible.

I was actually wondering how he did operator overload in Pascal... But
I made the assumption that _somewhere out there_ there was an OPascal
version that supported this... Is this the case? Or is there something
I don't know about in standard OPascal?

/Nic



Mon, 12 Dec 2005 14:58:29 GMT  
 FPC - wasted memory...

Quote:



>> Let me rephrase: Operator overloading and dynamic types (including classes)
>> are not possible.

> I was actually wondering how he did operator overload in Pascal... But
> I made the assumption that _somewhere out there_ there was an OPascal
> version that supported this... Is this the case? Or is there something
> I don't know about in standard OPascal?

FPC implemented it first, but only for static types. It seems the newest
Delphi also has something like that (I see it in the feature matrix), but
I don't know if it has it in the same way.


Mon, 12 Dec 2005 21:01:10 GMT  
 FPC - wasted memory...
I've not used FPC before, but is it possible, in the process of creating
your temp variable to store the subexpression result, to put the location
of the newly created temp variable in, say, a link list of temp variables
of that particular class?  Then at some point you can call:

someclass.destroytemps;

Which will traverse the list and destroy the temps created for that class.
(That point being at the end of procedures or looping blocks that use
variables of that class)

The small amount of overhead in an explicit call to someclass.destroytemps
when the list is empty (no temps created to this point) is a small price to
pay,
compare to the (*shudder*) workaround given elsewhere in this thread where
a pointer to released memory is used to access the temp data.

Rufus


Quote:
> Suppose we have a class type with overloaded operators:

> var a,b,c,d:someclass;

> and then

> c:=a+b;    // OK

> but:

> d:=a*b+c;

> works fine too, but some memory gets wasted - the program allocates a
class
> variable with a*b result which is not destroyed after resolving the whole
> expression, and there's not any reference to that variable. Is there any
way
> to solve this problem?

> of course one could do

> temp:=a*b;
> d:=temp+c;
> temp.destroy;

> but this is NOT the solution ;-)

> --
> Azarien

-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----==  Over 80,000 Newsgroups - 16 Different Servers! =-----


Wed, 14 Dec 2005 16:36:27 GMT  
 FPC - wasted memory...

Quote:

> I've not used FPC before, but is it possible, in the process of creating
> your temp variable to store the subexpression result, to put the location
> of the newly created temp variable in, say, a link list of temp variables
> of that particular class?  Then at some point you can call:

Hmm, this would be doable. Making some factory class that instantiates all
occurances of the type, and keeps a reference.

Then at the end, declare the final result to be non-temporary, and delete
all references like e.g. with:

Quote:
> someclass.destroytemps;
> Which will traverse the list and destroy the temps created for that class.
> (That point being at the end of procedures or looping blocks that use
> variables of that class)

> The small amount of overhead in an explicit call to someclass.destroytemps
> when the list is empty (no temps created to this point) is a small price to
> pay,
> compare to the (*shudder*) workaround given elsewhere in this thread where
> a pointer to released memory is used to access the temp data.

Good thinking, I like it! The only problem I can think of is using the same
factory in multiple threads.


Wed, 14 Dec 2005 21:54:19 GMT  
 FPC - wasted memory...

: > compare to the (*shudder*) workaround given elsewhere in this thread where
: > a pointer to released memory is used to access the temp data.

: Good thinking, I like it! The only problem I can think of is using the same
                   ^^^^
: factory in multiple threads.

I hope that quote above is not about accessing released memory. With
nested expressions there may be some time between finishing computing
a subexpression and using the result. If the memory menager is eager
it may reuse "free" memory and invalidate the result before it is used.
--
                              Waldek Hebisch



Thu, 15 Dec 2005 02:44:45 GMT  
 FPC - wasted memory...

Quote:


>: > compare to the (*shudder*) workaround given elsewhere in this thread where
>: > a pointer to released memory is used to access the temp data.

>: Good thinking, I like it! The only problem I can think of is using the same
>                    ^^^^
>: factory in multiple threads.
> I hope that quote above is not about accessing released memory.

No.

Quote:
> With nested expressions there may be some time between finishing computing
> a subexpression and using the result. If the memory menager is eager it
> may reuse "free" memory and invalidate the result before it is used.

No, since it must be explicitely set free. See it like this:

type
      factoryclass =class
                      function createsubtype(a:tvalue):subtypeclass;
                      procedure purge;
                      end;      

      subtypeclass = class(sometype)
                      valueofthisclass  : tvalue;      
                      constructor create(a:tvalue);
                      parent : factoryclass;
                      function getparent:factoryclass;  
                      procedure setpersistant;  
                      function add(a:subtypeclass):tvalue;
                      end;

operator + (a,b:subtypeclass):subtypeclass;

begin
  result:=a.getparent.createsubtype(a.add(b));;
end;    

Now assume that subtypeclass is a kind of expression tree. It parses
infix and keeps a parse tree.

var factory  : tfactoryclass;
     a,b,c,d : subtypeclass;

Begin
 factory:=tfactoryclass.create();
 a:=factory.create('5+a*x');
 b:=factory.create('b*x');
 c:=a+b*factory.create('c*x^2');
 d:=c+b;  
 d.setpresistant;
 factory.purge;                 // free's all but d.
end.

The trick is that if I can name the start and the ending of the calculation,
and create all intermediate expressions with the factory, tfactory can keep
a list of temps it has issued.

The operator overloaded functions can get to the factory via the parent
field of each subtypeclass, and use it to make all temps. I demonstrated
this for "add". The main reason for this is that you don't have to declare
a factory class global to the operator overloaded functions.

The programmer can remove variables (as end results) of the purgelist by
calling the setpersistant method (which makes a call to the factory class
to get it of the list)

A purge simply walks the lists in the factory and calls free on all of them.

It is explicit (you have to say "I start now, keep ocunting", but between
the factory creation and purging you don't have to keep track. It is also
not limited to one function. The local reference goes out of scope, but the
factory still got a tlist of issued temps.

This could probably get generalised by trying to describe the factory <->
subtypeclass interaction in some interfaces, but I haven't really played with
interfaces (which are FPC 1.1, the CVS development version) that much.



Thu, 15 Dec 2005 06:28:43 GMT  
 FPC - wasted memory...

Quote:
> type
>       factoryclass =class
>       function createsubtype(a:tvalue):subtypeclass;
>       procedure purge;
>       end;

>       subtypeclass = class(sometype)
>       valueofthisclass  : tvalue;
>       constructor create(a:tvalue);
>       parent : factoryclass;
>       function getparent:factoryclass;
>       procedure setpersistant;
>       function add(a:subtypeclass):tvalue;
>       end;

Semms that FPC does not allow..

  type foo=class
          getbar:bar;  <- Identifier not found BAR    
       end;

       bar=class
          getfoo:foo;
       end;

 * * *

  type bar=class
          getfoo:foo;  <- Identifier not found FOO
       end;

       foo=class
          getbar:bar;
       end;

?

--
Azarien



Thu, 15 Dec 2005 20:28:09 GMT  
 FPC - wasted memory...

Quote:

>> type
>>       factoryclass =class
>>       constructor create(a:tvalue);
>>       parent : factoryclass;
>>       function getparent:factoryclass;
>>       procedure setpersistant;
>>       function add(a:subtypeclass):tvalue;
>>       end;

> Semms that FPC does not allow..

All Pascals need to have types declared before usage!

Sometimes this can be workaround (for reference types) by forward declaring,
like in this case.

Quote:
>   type

         bar=class;

Quote:
>        foo=class
>           getbar:bar;  <- Identifier not found BAR    
>        end;

>        bar=class
>           getfoo:foo;
>        end;

This is described in the manual.


Thu, 15 Dec 2005 20:31:18 GMT  
 FPC - wasted memory...
No, the "good thinking" was saving references to the temp variables.  The
use of
pointers to released memory is what we were trying to avoid, but was offered
as
a dangerous, but currently successful workaround.

I don't think you need to explicitly "freeze" the last create.  What you do
is
link the references created by the overloaded binary operators.  Explicit
creates
are not placed in the "to be destroyed" list.

Rufus


Quote:

> : > compare to the (*shudder*) workaround given elsewhere in this thread
where
> : > a pointer to released memory is used to access the temp data.

> : Good thinking, I like it! The only problem I can think of is using the
same
>                    ^^^^
> : factory in multiple threads.

> I hope that quote above is not about accessing released memory. With
> nested expressions there may be some time between finishing computing
> a subexpression and using the result. If the memory menager is eager
> it may reuse "free" memory and invalidate the result before it is used.
> --
>                               Waldek Hebisch


-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----==  Over 80,000 Newsgroups - 16 Different Servers! =-----


Thu, 15 Dec 2005 14:15:35 GMT  
 FPC - wasted memory...

Quote:

> No, the "good thinking" was saving references to the temp variables.  The
> use of
> pointers to released memory is what we were trying to avoid, but was offered
> as
> a dangerous, but currently successful workaround.

> I don't think you need to explicitly "freeze" the last create.  What you do
> is
> link the references created by the overloaded binary operators.  Explicit
> creates
> are not placed in the "to be destroyed" list.

The last temp reference is also the result.

Adding the explicit references can be simply fixed by having two
constructors. One (for internal use) adds them to the list, one not.

But in the application I'm thinking of (and used in the example, an
expression handling system) I generally want the used constants to be
destructed.

Note that the factory could be expanded with a trick to reuse objects (e.g.
by having the objects have a "clean" method or so).

This would be very useful for my application since the dynamic objects
themselves contain parsetrees. I could pool the used parsetree reocrds,
and save on allocating overhead in such example. (because an "add" would
mean copying two parsetrees to a new one). Still horribly inefficient, but
already better. Speed is not really an issue at that point anyway.



Thu, 15 Dec 2005 21:31:39 GMT  
 
 [ 40 post ]  Go to page: [1] [2] [3]

 Relevant Pages 

1. FPC - wasted memory - solution ?

2. FPC Win32 memory mapped files for IPC

3. FPC Win32 memory mapped files for IPC

4. FPC, TMT, and memory usage.

5. FPC: ^longint type, memory question

6. FPC:problem with printing from fpc programs

7. FPC: translate execvp from c to FPC

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

9. Pascal a waste of time?

10. New Strategy Game: Blasted Wastes

11. Table repair with TUtility - a waste of time?

12. multi threading in fpc linux?

 

 
Powered by phpBB® Forum Software