Hi!
I have a communication debugger program for RS485 bus. It works, but with heaptrace i got a bunch of memory leak.
It have two records, one for virtualstringtree (to display comm packets) and one for transporting data from the reciever / transmitter to the virtualtree.
type
PLogTreeData = ^TLogTreeData;
TLogTreeData = record
time: TDateTime;
Sender: string;
Address: string;
Len: string;
Rnd: string;
Msn: string;
CmdCode: string;
Direction: string;
CRC_readed: string;
CRC_calced: string;
Message: array of byte;
end;
PLogLineData = ^TLogLineData;
TLogLineData = record
Time: TDateTime;
Sender: string;
Address: string;
Len: string;
Rnd: string;
Msn: string;
CmdCode: string;
Direction: string;
CRC_readed: string;
CRC_calced: string;
Message: array of byte;
end;
The transmitter and the receiver procedures are mostly the same, so i just post the transmitter procedure.
procedure FillTxbuff(CMD_H: integer; CMD_L: integer; LEN: integer; Data: array of byte; Broadcast: boolean);
var
tbytes: array[0..BYTEMAX] of byte;
LogMsg: TLogLineData;
LogMsgPtr: PLogLineData;
begin
...
LogMsgPtr := @LogMsg;
SetLength(LogMsgPtr^.Message, tbytes[3]);
for i:=0 to tbytes[3] - 1 do begin
LogMsgPtr^.Message[i] := tbytes[i];
end;
LogMsgPtr^.Time := Now;
LogMsgPtr^.Direction:='out';
LogMsgPtr^.Address:= 'L: '+IntToStr(tbytes[1])+' H: '+IntToStr(tbytes[2]);
if tbytes[2] > 127 then begin
LogMsgPtr^.Sender := 'master';
end else begin
LogMsgPtr^.Sender := 'slave';
end;
LogMsgPtr^.Len := IntToStr(tbytes[3]);
LogMsgPtr^.Rnd := IntToStr(tbytes[4]);
LogMsgPtr^.Msn := IntToStr(tbytes[5]);
//////////////////////////////////////////////
RS485EncryptData(tbytes[3] - 5, 4, tbytes);
tbytes[tbytes[3] - 1] := ArrayCRC08Calc(tbytes, tbytes[3]-1);
LogMsgPtr^.CRC_readed := '';
LogMsgPtr^.CRC_calced := tbytes[tbytes[3] - 1].ToHexString();
if (tbytes[3] = 7) and (ShowVoid = true) then begin
MainForm.AddNewLineToLogTree(LogMsgPtr);
end else if tbytes[3] > 7 then begin
LogMsgPtr^.CmdCode := '0x'+IntToHex(tbytes[7], 2) + IntToHex(tbytes[6], 2);
MainForm.AddNewLineToLogTree(LogMsgPtr);
end;
Move(tbytes, txbuff, tbytes[3]);
MainForm.TxLed.Color:=clRed;
MainForm.TxClear.Enabled:=true;
SbFlag := true;
end;
So i'm passing a pointer of a local variable here to an other procedure.
This is the procedure what puts the data to the gui:
procedure TMainForm.AddNewLineToLogTree(MessageLine: PLogLineData);
var
xnode: PVirtualNode;
data: PLogTreeData;
begin
LogTree.BeginUpdate;
xnode:=LogTree.AddChild(nil);
data:=LogTree.GetNodeData(xnode);
data^.time:=MessageLine^.Time;
data^.Sender:=MessageLine^.Sender;
data^.Direction:=MessageLine^.Direction;
data^.Address:=MessageLine^.Address;
data^.Len:=MessageLine^.Len;
data^.Rnd:=MessageLine^.Rnd;
data^.Msn:=MessageLine^.Msn;
data^.CRC_calced:=MessageLine^.CRC_calced;
data^.CRC_readed:=MessageLine^.CRC_readed;
data^.CmdCode:=MessageLine^.CmdCode;
SetLength(data^.Message, data^.Len.ToInteger);
data^.Message:=MessageLine^.Message;
LogTree.EndUpdate;
And that's all. Whit these code, i'm getting many memory leaks in heaptrace output.
Call trace for block $000000000BA248F0 size 36
$0000000100012672
$0000000100009FE3
$000000010000B23C
$000000010000A82F
$000000010004B65A line 194 of rs485_utils.pas
$000000010004BA48 line 235 of rs485_utils.pas
$0000000100051CED line 1218 of main.pas
$00000001001DE896 line 175 of customtimer.pas
Call trace for block $000000000BA24D70 size 23
$0000000100012672
$000000010000EE32
$000000010004B56C line 187 of rs485_utils.pas
$000000010004BA48 line 235 of rs485_utils.pas
$0000000100051CED line 1218 of main.pas
$00000001001DE896 line 175 of customtimer.pas
$00000001001DE7D9 line 150 of customtimer.pas
$000000010013F47D line 2843 of win32callback.inc
...
And so on. These lines are various LogMsgPtr^... lines of the FillTxbuff procedure. What I'm doing wrong?