[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