Corrupted /how/? What's your error message? How do you know that the length is >= 0?
MarkMLl
What about if you move hd from procedure to global var ?
Are you sure the error is on the SetLength() line?
(How did you check?)
Are you sure the instance of TForm1 is created?
How and where do you call ReadHistoryTrafficData?
And I also check it by adding a lot of lines of MessageDlg() to ensure I know where I was.
Hi all,
I got a procedure in which SetLength is used. But everytime when it run to SetLength line, the program corrupted. I guess it is a very simple stupid problem. But I just can't figure it out. Who can remind me something about it?
type PTrafficRecord = ^TrafficRecord; TrafficRecord = record Time:TDateTime; Interval:integer; Volume:integer; Index:integer; end; procedure TForm1.ReadHistoryTrafficData(const IndexFrom:integer;const IndexTo:integer); var hd:array of TrafficRecord; i,Len:integer; begin if IndexFrom>IndexTo then exit; Len:=IndexTo-IndexFrom+1; SetLength(hd,Len); //program corrupted here!! for i:=0 to IndexTo-IndexFrom do begin //do something end; SetLength(hd,0); end;
I have prepared a little test. Here is the code:
unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls; type PTrafficRecord = ^TTrafficRecord; TTrafficRecord = record Time: TDateTime; Interval: Integer; Volume: Integer; Index: Integer; end; {TForm1} TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private procedure ReadHistoryTrafficData(const AIndexFrom, AIndexTo: Integer); public end; var Form1: TForm1; implementation {$R *.lfm} {TForm1} procedure TForm1.Button1Click(Sender: TObject); begin ReadHistoryTrafficData(1, 10); end; procedure TForm1.ReadHistoryTrafficData(const AIndexFrom, AIndexTo: Integer); var VItem: PTrafficRecord; VData: array of PTrafficRecord; i, VCount, VSize: Integer; VCurrentTime: TTime; VText: String; begin if AIndexFrom > AIndexTo then Exit; VCount := AIndexTo - AIndexFrom + 1; SetLength(VData, VCount); Memo1.Lines.Clear; VCurrentTime := Now; Randomize; VSize := 0; for i := 0 to AIndexTo - AIndexFrom do begin New(VItem); VItem^.Index := i; VItem^.Time := Now; VItem^.Interval := Trunc(VCurrentTime - VItem^.Time); VItem^.Volume := Random(1000); VData[i] := VItem; VSize := VSize + SizeOf(VItem^); VText := 'i = ' + i.ToString + ', time: ' + TimeToStr(VItem^.Time) + ', interval: ' + VItem^.Interval.ToString + ', volume: ' + VItem^.Volume.ToString; Memo1.Lines.Add(VText); end; Memo1.Lines.Add('-----'); Memo1.Lines.Add('n: ' + VCount.ToString); Memo1.Lines.Add('structure size: ' + VSize.ToString); SetLength(VData, 0); end; end.
The code compiles. I also checked it with a debugger. I am not getting any error messages. I'm using: Windows 10, Lazarus 2.0.10.
VisualLab
You don't want to read into ARR, that is a space for the 4/8 byte large pointer.
fs.read into arr[0]
So, another lesson for me: problem often happens before you can see it. Seek the real bug before the crash point.