Hi,
I have a problem with a large program I wrote, under certain conditions I get access violations when I exit the program (but not as far I tried when it's still running).
I've narrowed it down to the following part, it's a routine that only gets called by the object's constructor (FX- and FYmotionTables are private members of TElementImageTranslation):
If I comment the part in bold, and replace the last loop with:
Then I get no crashes at program shutdown anymore (although the functionality of the code is lost, because it only addresses one case. Strangely enough, these crashes only happen if during runtime I generate 3 or more of these objects (each separately by allocating a pointed and calling the constructor).
I realize I can get around the issue in various ways, but my question here is about understanding the reference count that is supposed to control allocation of memory for the arrays. As I understand it, after the following lines:
We have MovingTable and StillTable referencing the same arrays as FYmotiontable and FXmotiontable respectively, and this bears out because the assignments in the loop correctly change the values in the two latter arrays. When the function finishes, MovingTable and StillTable die, bumping the references to FYmotiontable and FXmotiontable down to one each, so when these objects are destroyed, there are only these references left and the garbage collector should free the memory as expected. But it doesn't, and I get the access violations when the program terminates (but not when I dereference the objects themselves).
What am I getting wrong here? Any suggestions?
I have a problem with a large program I wrote, under certain conditions I get access violations when I exit the program (but not as far I tried when it's still running).
I've narrowed it down to the following part, it's a routine that only gets called by the object's constructor (FX- and FYmotionTables are private members of TElementImageTranslation):
Code:
procedure TElementImageTranslation.GenerateXYmotionTables;
var
NFrames, FirstFrame: Integer; //number of frames for motion
MovePerSec, MovePerFrame, PixPerDeg: Double; //number of pixels to move per second/frame
i, FrameRate: Integer;
MovingTable, StillTable: ArrSmallInt;
isNegative: Boolean;
begin
FrameRate := vsgGetSystemAttribute(vsgFRAMERATE);
NFrames := Max(Ceil((Offset - Onset)*FrameRate),1);
...
//allocate memory for the XYmotion tables
SetLength(FXmotiontable, NFrames);
SetLength(FYmotiontable, NFrames);
//translate the deg/sec units to pix/sec
vsgUnitToUnit(vsgDEGREEUNIT,1,vsgPIXELUNIT,PixPerDeg);
MovePerSec := SpeedTranslation * PixPerDeg;
// Video pages go in the Y direction and depend on how many frames in this direction
// fit on the video page (which is 1024 pixels high)
NVideoPages := ceil((NFrames*MovePerSec/FrameRate+480)/1024);
FirstFrame := round(FStartingAngle*PixPerDeg);
[b]case FTransDirection of
TTD_Left: begin
MovePerFrame :=MovePerSec/FrameRate;
MovingTable := FXmotiontable;
StillTable := FYmotiontable;
end;
TTD_Right: begin
MovePerFrame := -MovePerSec/FrameRate;
MovingTable := FXmotiontable;
StillTable := FYmotiontable;
end;
TTD_Up: begin
MovePerFrame := -MovePerSec/FrameRate;
MovingTable := FYmotiontable;
StillTable := FXmotiontable;
end;
TTD_Down: begin
MovePerFrame := MovePerSec/FrameRate;
MovingTable := FYmotiontable;
StillTable := FXmotiontable;
end;
end;
[/b]
isNegative := false;
for i:= 0 to NFrames do
begin
StillTable[i] := 0;
MovingTable[i] := FirstFrame + round(i*MovePerFrame);
isNegative := isNegative or (MovingTable[i] < 0);
end;
...
end;
If I comment the part in bold, and replace the last loop with:
Code:
for i:= 0 to NFrames do
begin
FXmotiontable[i] := 0;
FYmotiontable[i] := FirstFrame + round(i*MovePerFrame);
isNegative := isNegative or (FYmotiontable[i] < 0);
end;
Then I get no crashes at program shutdown anymore (although the functionality of the code is lost, because it only addresses one case. Strangely enough, these crashes only happen if during runtime I generate 3 or more of these objects (each separately by allocating a pointed and calling the constructor).
I realize I can get around the issue in various ways, but my question here is about understanding the reference count that is supposed to control allocation of memory for the arrays. As I understand it, after the following lines:
Code:
TTD_Down: begin
MovePerFrame := MovePerSec/FrameRate;
MovingTable := FYmotiontable;
StillTable := FXmotiontable;
end;
What am I getting wrong here? Any suggestions?