Show quoted text 6 lines
On Sat, 22 Sep 2001, Jonas Maebe wrote:
>
> On Sat, 22 Sep 2001 wrote:
>
> > I have a problem where FPC modifies a pointer without me
instructing it
Show quoted text 10 lines
> > to do so.
> > With stucture :
> > Type
> > PAnsiString = ^AnsiString;
> > PPAnsiString = ^PAnsiString;
> >
> > Var
> > RowAP : ^PPAnsiString;
> >
> > I first create two rows (that are the ansistrings in a pointer of array
of
> > pointer of ansistring structure) and set some data into them. After
that I
> > add one row between these two and initialize it with exactly these
rows :
Show quoted text 7 lines
> >
> > GetMem(RowAP^[1], SizeOf(AnsiString));
> > Writeln(LongInt(RowAP^[2]));
> > RowAP^[1]^ := 'a';
> > Writeln(LongInt(RowAP^[2]));
> >
> > The program outputs two lines that are : "4284808" and "4284807"
(the
> > values differ of course, but not the difference) which isn't right. I
can't
> > reproduce this in other programs (haven't tried very extensively)
but I
> > don't think that I could ever mess up my program to produce this
kind of
> > thing.
>
> You are doing very dangerous things. Ansistrings are reference
counted,
> which measn that the compiler normally does a lot of things behind
your
Show quoted text 13 lines
> back. With the above construction, it fails to do these things...
>
> You have to intialize all memory you allocate this way for storing
> ansistrings in explcitely with 0 before storing an ansistring in them, or
> you may get random memory corruption.
>
> I don't know whether the compile should do that automatically in this
> case, it's possible it should (but it definitely doesn't currently)
It doesn't do it, and isn't supposed to do it. Only New() will initialize
any memory for use with ansistrings. When using GetMem() you should
explicitly zero out any memory that should be occuped by ansistrings
before using it. Failing to do so may and will result in memory
corruption.
In the above case, this should definitely be done.
I agree with Michael about that. The problem is (at least I think that it's) that most pascal programmers don't think ansistring as a pointer. Also note that you can't do a New(AnsiStringVar); and implementing this will require it to properly handle the reference count.
By the way. My
Var
TempL : ^LongInt;
A : AnsiString;
B : AnsiString;
Begin
A := 'Blaah3';
B := A;
TempL := Pointer(A);
Dec(TempL);
Writeln(TempL^);
End.
- proggie returns -1. Is reference counting working?
________________________________________________________________ Ilmainen Internet @ http://www.nic.fi/