[fpc-pascal]The compiler messes up some pointers.
yendor at nic.fi
yendor at nic.fi
Sat Sep 22 23:58:39 CEST 2001
Michael.VanCanneyt at Wisa.be wrote:
>
> On Sat, 22 Sep 2001, Jonas Maebe wrote:
> >
> > On Sat, 22 Sep 2001 yendor at nic.fi wrote:
> >
> > > I have a problem where FPC modifies a pointer without me
instructing it
> > > 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 :
> > >
> > > 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
> > 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/
More information about the fpc-pascal
mailing list