[fpc-pascal] Re: Problems with assigning pointers

Sven Barth pascaldragon at googlemail.com
Wed Apr 11 09:26:13 CEST 2012


Am 10.04.2012 22:16, schrieb Vincent Snijders:
> Op 10 april 2012 22:06 heeft Darius Blaszyk<dhkblaszyk at zeelandnet.nl>
> het volgende geschreven:
>> Here's a minimal example that has the bug. First of all the first output is wrong as it says 0,50 instead of 20,50 (so the x item is overwritten). The second printed output differs from the first, so again the x item is overwritten. I'm clueless.
>>
>> program test;
>>
>> {$mode objfpc}{$H+}
>>
>> type
>>   TVertex = record
>>     x: double;
>>     y: double;
>>   end;
>>   PVertex = ^TVertex;
>>
>>   TEdge = record
>>     v1: PVertex;
>>     v2: PVertex;
>>   end;
>>
>> var
>>   vert_count: integer = 0;
>>   vert_list: array of TVertex;
>>   edge_count: integer = 0;
>>   edge_list: array of TEdge;
>>
>> function add_vert(x, y: double): PVertex;
>> begin
>>   Inc(vert_count);
>>   SetLength(vert_list, vert_count);
>>
>>   vert_list[vert_count - 1].x := x;
>>   vert_list[vert_count - 1].y := y;
>>
>>   Result := @vert_list[vert_count - 1];
>
> I think this is not correct. If you increase the size of vert_list,
> then the array may be relocated and Result isn't a valid pointer
> anymore.
>

This is indeed the problem.

>> end;
>>
>> procedure add_edge(v1, v2: PVertex);
>> begin
>>   Inc(edge_count);
>>   SetLength(edge_list, edge_count);
>>
>>   WriteLn(v1^.x,' ',v1^.y); // this
>>   edge_list[edge_count - 1].v1 := v1;
>>   WriteLn(v1^.x,' ',v1^.y); // outputs the same thing as this
>>   edge_list[edge_count - 1].v2 := v2;
>> end;
>>
>> var
>>   v1: PVertex;
>>   v2: PVertex;
>>
>> begin
>>   v1 := add_vert(20, 50);
>>   v2 := add_vert(220, 50);

Your pointer to v1 is already invalid here, because the second 
"add_vert" already changed the location of the array and thus the new 
pointer locations are also different.

>>
>>   add_edge(v1, v2);
>>
>>   readln;
>> end.
>>

A better solution if you want to keep the "vertex array" would be to 
have an array of "PVertex" instead of "TVertex". You then need to do a 
"New(Result)" in your "add_vertex" function and add that "Result" to the 
enlarged array. Similiary you'll need to do a "Dispose(...)" in some 
"remove_vertex" procedure.

Regards,
Sven



More information about the fpc-pascal mailing list