Board index » delphi » Smart pointers in Delphi, are there any?

Smart pointers in Delphi, are there any?

Once again please don't flame me for asking a question because I come from a
C++ background.

Is there a "smart" pointer class for Delphi that allows memory sharing and
memory copy on write type functionality? I know it would not be as simple to
use as in stack based languages (ie. languages that create objects on the
stack to allow auto destruction when leaving the scope they were created
in), but at least the copy on write functionality with structure sharing
would be nice.

 

Re:Smart pointers in Delphi, are there any?


Quote
Jeff Lindholm wrote in message ...
>Once again please don't flame me for asking a question because I come from
a
>C++ background.

Oh? Did we do that? (-:

Quote
>Is there a "smart" pointer class for Delphi that allows memory sharing and
>memory copy on write type functionality? I know it would not be as simple
to
>use as in stack based languages (ie. languages that create objects on the
>stack to allow auto destruction when leaving the scope they were created
>in), but at least the copy on write functionality with structure sharing
>would be nice.

Long strings do this, but nothing else that I know of.

The usual work-around, to call it that (frankly I believe
that allocating objects on the stack is a mistake), is:

X:=TX.Create;
try
  { Do your thing here }
finally
  X.Free;
end;

where X is a local variable of class TX (or some superclass
thereof). This fits in with the reality that in Delphi,
object memory allocation is implicit in the constructor call.
And that you have to free your own objects, yes.

I don't really see why you would want copy-on-write. Is it
not objects you are after? It's not random that _strings_
are copy-on-write; they're not objects. When changing an
object, one would expect the object to change. Not clone or
something. And the term _structure_ sharing puzzles me as
well.

Perhaps you could wing it by encoding data in strings. You
can actually store binary data in them; their length is
determined by a length field, not by the first NUL character.

Groetjes,
Maarten Wiltink

Re:Smart pointers in Delphi, are there any?


On Thu, 17 Jan 2002 00:02:07 +0100, "Maarten Wiltink"

Quote
<maar...@kittensandcats.net> wrote:

>Long strings do this, but nothing else that I know of.

Well, not compleete I guess.

Found some interesting memory leakages from strings if you are
'stupid' enough to do this:

pLeakingMemoryRecord = ^tLeakingMemoryRecord;
tLeakingMemoryRecord = Record
   LeakyString : String;
end:

in use:

aLeakyStringRecordd := New(pLeakingMemoryRecord);

aLeakyStringRecordd^.LeakyString := 'A leaking text';

dispose(aLeakyStringRecordd);
aLeakyStringRecordd:=NIL;

In this case the memory of Leakystring is never deallocated :-(
You must say:

WITH aLeakyStringRecordd^ DO
  BEGIN
    .LeakyString := '';
  (<evt. other deallocatins of pointers in the record)
  END;
dispose(aLeakyStringRecordd);
aLeakyStringRecordd:=NIL;

If you have pointers in a record, it is a good idea to write a
disposing routing that do all deallocations etc. for you.

Re:Smart pointers in Delphi, are there any?


Quote
"Alf Christophersen" <alf.christopher...@basalmed.uio.no> wrote in message
> Found some interesting memory leakages from strings if you are
> 'stupid' enough to do this:

How did you determine that there was a memory leak?

Quote

> pLeakingMemoryRecord = ^tLeakingMemoryRecord;
> tLeakingMemoryRecord = Record
>    LeakyString : String;
> end:

> in use:

> aLeakyStringRecordd := New(pLeakingMemoryRecord);

AFAIK there is no New function in ObjectPascal. Is this your own function?
The correct way to allocate a new record dynamically is (presuming that
aLeakyStringRecordd is declared as a pLeakingStringMemoryRecord)

    New (aLeakyStringRecordd);

Quote

> aLeakyStringRecordd^.LeakyString := 'A leaking text';

> dispose(aLeakyStringRecordd);
> aLeakyStringRecordd:=NIL;

> In this case the memory of Leakystring is never deallocated :-(

With the correction noted there is no memory leak. As documented in the help
Dispose calls Finalize on the record instance before releasing the memory.

Quote
> You must say:

> WITH aLeakyStringRecordd^ DO
>   BEGIN
>     .LeakyString := '';

The above line won't compile.

Quote
>   (<evt. other deallocatins of pointers in the record)
>   END;
> dispose(aLeakyStringRecordd);
> aLeakyStringRecordd:=NIL;

> If you have pointers in a record, it is a good idea to write a
> disposing routing that do all deallocations etc. for you.

This is false. The only time one must write custom release code is when the
record contains class instances and/or untyped pointers.

Re:Smart pointers in Delphi, are there any?


Just a minor correction, and completely unneccessary if delphi (i'm no  sure
about this) treats a record variable as a pointer (as it does array
variables), but assuming it doesn't then we do new(pLeakyString) as new
takes a typed pointer and allocates the memory required for the type it
poins to, now we can access it as pleakystring^.leakystring... :)

--Oliver

Quote
> > pLeakingMemoryRecord = ^tLeakingMemoryRecord;
> > tLeakingMemoryRecord = Record
> >    LeakyString : String;
> > end:

> > in use:

> > aLeakyStringRecordd := New(pLeakingMemoryRecord);

> AFAIK there is no New function in ObjectPascal. Is this your own function?
> The correct way to allocate a new record dynamically is (presuming that
> aLeakyStringRecordd is declared as a pLeakingStringMemoryRecord)

>     New (aLeakyStringRecordd);

New(pLeakyStringRecordd)

- Show quoted text -

Quote

> > aLeakyStringRecordd^.LeakyString := 'A leaking text';

> > dispose(aLeakyStringRecordd);
> > aLeakyStringRecordd:=NIL;

> > In this case the memory of Leakystring is never deallocated :-(

> With the correction noted there is no memory leak. As documented in the
help
> Dispose calls Finalize on the record instance before releasing the memory.

> > You must say:

> > WITH aLeakyStringRecordd^ DO
> >   BEGIN
> >     .LeakyString := '';

> The above line won't compile.

> >   (<evt. other deallocatins of pointers in the record)
> >   END;
> > dispose(aLeakyStringRecordd);
> > aLeakyStringRecordd:=NIL;

> > If you have pointers in a record, it is a good idea to write a
> > disposing routing that do all deallocations etc. for you.

> This is false. The only time one must write custom release code is when
the
> record contains class instances and/or untyped pointers.

Re:Smart pointers in Delphi, are there any?


On Thu, 17 Jan 2002 13:32:03 -0500, "Bruce Roberts"

Quote
<b...@bounceitattcanada.xnet> wrote:

>How did you determine that there was a memory leak?

By running a program in MemProof. Search for Memproof on the net and
you find it some places for download. Very useful for determining
leakages and overwrites.

Re:Smart pointers in Delphi, are there any?


Quote
Bruce Roberts <b...@bounceitattcanada.xnet> wrote in message

news:57F18.410$EI.1824@tor-nn1.netcom.ca...

Quote

[ some stuff ]
> > If you have pointers in a record, it is a good idea to write a
> > disposing routing that do all deallocations etc. for you.

> This is false. The only time one must write custom release code is when
the
> record contains class instances and/or untyped pointers.

Bruce, is this documented somewhere?  I treat such situations with
suspicion, and always check with Memproof, but it would be nice to know if
it has actually been formalised somewhere.

Dave

Re:Smart pointers in Delphi, are there any?


Quote
"Oliver Hunt" <nospamre...@bigfoot.com> wrote in message

news:3c474fcc@clear.net.nz...

Quote
> Just a minor correction, and completely unneccessary if delphi (i'm no
sure
> about this) treats a record variable as a pointer (as it does array
> variables), but assuming it doesn't then we do new(pLeakyString) as new
> takes a typed pointer and allocates the memory required for the type it
> poins to, now we can access it as pleakystring^.leakystring... :)
> > AFAIK there is no New function in ObjectPascal. Is this your own
function?
> > The correct way to allocate a new record dynamically is (presuming that
> > aLeakyStringRecordd is declared as a pLeakingStringMemoryRecord)

> >     New (aLeakyStringRecordd);

> New(pLeakyStringRecordd)

No Delphi doesn't treat a record variable as a pointer. A record variable
allocates SizeOf (record type) bytes of memory. However, you will note that
the presumption was that aLeakyStringRecordd was of type
pLeakingStringMemoryRecord which is a pointer. So the correct syntax for
allocation aLeakyStringRecordd is in fact that which I posted.

Re:Smart pointers in Delphi, are there any?


Quote
"Alf Christophersen" <alf.christopher...@basalmed.uio.no> wrote in message

news:3c476942.8452826@nntp.uio.no...

Quote
> On Thu, 17 Jan 2002 13:32:03 -0500, "Bruce Roberts"
> <b...@bounceitattcanada.xnet> wrote:

> >How did you determine that there was a memory leak?

> By running a program in MemProof. Search for Memproof on the net and
> you find it some places for download. Very useful for determining
> leakages and overwrites.

Since what you posted wouldn't compile I'm surprised that MemProof was able
to report a leak with the code. I stand by my assertions and doubt that
MemProof would report an error with the corrected code. If it does it is
wrong.

Re:Smart pointers in Delphi, are there any?


Quote
"David Reeve" <drscienti...@powerup.com.au> wrote in message news:4LM18.4960
> Bruce, is this documented somewhere?  I treat such situations with
> suspicion, and always check with Memproof, but it would be nice to know if
> it has actually been formalised somewhere.

See the help entry on the Finalize procedure.

Re:Smart pointers in Delphi, are there any?


On Fri, 18 Jan 2002 00:30:16 -0500, "Bruce Roberts"

Quote
<b...@bounceitattcanada.xnet> wrote:
>Since what you posted wouldn't compile I'm surprised that MemProof was able
>to report a leak with the code. I stand by my assertions and doubt that
>MemProof would report an error with the corrected code. If it does it is
>wrong.

I have aq feeling you didn't get the point. It is the content of the
'string' variable that is not freed up when you dispose the record
that contains the pointer. If you use an old type of string with limit
of 255 chars nothing wrong happens, but if you have enable the
extended string and have a string of eg. 1000 chars, this will not be
disposed, because you must specifically say astring := '';

Re:Smart pointers in Delphi, are there any?


Quote
Alf Christophersen <alf.christopher...@basalmed.uio.no> wrote in message

news:3c48b6cd.9452094@nntp.uio.no...

Quote
> On Fri, 18 Jan 2002 00:30:16 -0500, "Bruce Roberts"
> <b...@bounceitattcanada.xnet> wrote:

> >Since what you posted wouldn't compile I'm surprised that MemProof was
able
> >to report a leak with the code. I stand by my assertions and doubt that
> >MemProof would report an error with the corrected code. If it does it is
> >wrong.

> I have aq feeling you didn't get the point. It is the content of the
> 'string' variable that is not freed up when you dispose the record
> that contains the pointer. If you use an old type of string with limit
> of 255 chars nothing wrong happens, but if you have enable the
> extended string and have a string of eg. 1000 chars, this will not be
> disposed, because you must specifically say astring := '';

As Bruce suggests, check help under Finalize procedure. You'll see that such
strings are emptied before the reference is freed.

The following does not leak memory as seen by Memproof...............

type
 pLeakingMemoryRecord = ^tLeakingMemoryRecord;
 tLeakingMemoryRecord = Record
   LeakyString : String;
 end;

procedure TForm1.Button1Click(Sender: TObject);
var
 aLeakyStringRecordd: pLeakingMemoryRecord;
begin
 New(aLeakyStringRecordd);
 aLeakyStringRecordd^.LeakyString := 'A leaking text';
  dispose(aLeakyStringRecordd);
end;

Dave

Re:Smart pointers in Delphi, are there any?


On Sat, 19 Jan 2002 12:13:58 +1000, "David Reeve"

Quote
<drscienti...@powerup.com.au> wrote:

>Alf Christophersen <alf.christopher...@basalmed.uio.no> wrote in message
>news:3c48b6cd.9452094@nntp.uio.no...
>The following does not leak memory as seen by Memproof...............

>type
> pLeakingMemoryRecord = ^tLeakingMemoryRecord;
> tLeakingMemoryRecord = Record
>   LeakyString : String;
> end;

>procedure TForm1.Button1Click(Sender: TObject);
>var
> aLeakyStringRecordd: pLeakingMemoryRecord;
>begin
> New(aLeakyStringRecordd);
> aLeakyStringRecordd^.LeakyString := 'A leaking text';
>  dispose(aLeakyStringRecordd);
>end;

Well, in my version of memproof, it did.
(But, maybe you need to use bigger text? I guess optimizer will use a
shortstring in your case. My texts was several kb huge. And they was
not disposed at all.

Re:Smart pointers in Delphi, are there any?


Quote
Alf Christophersen <alf.christopher...@basalmed.uio.no> wrote in message

news:3c4b06de.22418914@nntp.uio.no...

Quote
> On Sat, 19 Jan 2002 12:13:58 +1000, "David Reeve"
> <drscienti...@powerup.com.au> wrote:

> >Alf Christophersen <alf.christopher...@basalmed.uio.no> wrote in message
> >news:3c48b6cd.9452094@nntp.uio.no...
> >The following does not leak memory as seen by Memproof...............

> >type
> > pLeakingMemoryRecord = ^tLeakingMemoryRecord;
> > tLeakingMemoryRecord = Record
> >   LeakyString : String;
> > end;

> >procedure TForm1.Button1Click(Sender: TObject);
> >var
> > aLeakyStringRecordd: pLeakingMemoryRecord;
> >begin
> > New(aLeakyStringRecordd);
> > aLeakyStringRecordd^.LeakyString := 'A leaking text';
> >  dispose(aLeakyStringRecordd);
> >end;

> Well, in my version of memproof, it did.
> (But, maybe you need to use bigger text? I guess optimizer will use a
> shortstring in your case. My texts was several kb huge. And they was
> not disposed at all.

Hmmm.... lets see

procedure TForm1.Button1Click(Sender: TObject);
var
 aLeakyStringRecordd: pLeakingMemoryRecord;
 i: integer;
begin
 New(aLeakyStringRecordd);
 SetLength(aLeakyStringRecordd^.LeakyString, 10000);
 for i := 1 to 10000 do
   aLeakyStringRecordd^.LeakyString[i] := 'B';
  dispose(aLeakyStringRecordd);
end;

Still no leak.

Tried making aleakyStringrecordd global, and calling dispose on a separate
button click and still no leak.
I'm reasonably happy that the help files mean what they say.

D4 and MemProof  9.3.2 and Hook.dll 9.3.0

Dave

Re:Smart pointers in Delphi, are there any?


Quote
"Jeff Lindholm" <jeff_n...@lindholm.org> wrote in message news:sYl18.506
> Is there a "smart" pointer class for Delphi that allows memory sharing and
> memory copy on write type functionality? I know it would not be as simple
to
> use as in stack based languages (ie. languages that create objects on the
> stack to allow auto destruction when leaving the scope they were created
> in), but at least the copy on write functionality with structure sharing
> would be nice.

Its not clear to me why you want the functionality you describe. My
suggestion to you would be to post a brief description of what it is exactly
you are trying to do. In my experience trying to write a C++ solution in
ObjectPascal can be onerous. Its usually much simpler to use an ObjectPascal
approach. The paradigms of the two languages are different which often leads
to significant differences in the details of solutions to the same problem.

Other Threads