-
Content Count
51 -
Joined
-
Last visited
Everything posted by Alberto Paganini
-
I have one more memory leak to fix. Here is the report from FastMM4 --------------------------------2020/6/23 14:34:20-------------------------------- A memory block has been leaked. The size is: 116 This block was allocated by thread 0x157C, and the stack trace (return addresses) at the time was: 404DA6 [System.pas][System][@GetMem$qqri][3454] 408BBB [System.pas][System][@NewUnicodeString$qqri][19030] 408DEC [System.pas][System][@UStrFromPWCharLen$qqrr20System.UnicodeStringpbi][19697] 40A0C9 [System.pas][System][@UStrCopy$qqrx20System.UnicodeStringii][24873] E5CAD3 [Data.DBXPlatform.pas][Data.DBXPlatform][Dbxplatform.TDBXStringBuffer.ToString$qqrv][697] E8E8BC [Data.DBXJSON.pas][Data.DBXJSON][Dbxjson.TJSONString.Value$qqrv][1541] E9297C [uBetFair.pas][uBetFair][TBetFairApi.GetToken$qqrv][222] E92E90 [uTokenBL.pas][uTokenBL][TTokenBL.GetToken$qqrv][30] E5B593 [Main.pas][Main][TMainForm.FormActivate$qqrp14System.TObject][402] 557ED9 [Vcl.Forms][Forms.TCustomForm.Activate$qqrv] 558F99 [Vcl.Forms][Forms.TCustomForm.CMActivate$qqrr27Winapi.Messages.TWMNoParams] 4B4930 [Vcl.Controls.pas][Vcl.Controls][Controls.TControl.WndProc$qqrr24Winapi.Messages.TMessage][7204] 75C3C431 [Unknown function at gapfnScSendMessage] 75C3C3EE [Unknown function at gapfnScSendMessage] 75C3C380 [Unknown function at gapfnScSendMessage] The block is currently used for an object of class: UnicodeString The allocation number is: 60573 Current memory dump of 256 bytes starting at pointer address 7F2C7580: B0 04 02 00 01 00 00 00 2C 00 00 00 53 00 31 00 45 00 41 00 66 00 64 00 33 00 33 00 51 00 61 00 57 00 35 00 77 00 36 00 53 00 49 00 62 00 2F 00 69 00 4B 00 4F 00 6E 00 6F 00 32 00 74 00 47 00 36 00 74 00 63 00 36 00 4F 00 51 00 69 00 45 00 74 00 73 00 6C 00 6E 00 70 00 45 00 57 00 45 00 77 00 3D 00 00 00 31 8D A4 0F 80 80 80 80 80 80 80 80 80 80 80 80 80 80 00 00 00 00 21 80 2C 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E1 0C 01 00 A6 4D 40 00 0F 6E 40 00 7E 74 40 00 2B 97 DB 00 6D 80 DC 00 9B D1 CD 00 7A 3A D5 00 68 39 CD 00 D4 39 CD 00 62 8F DC 00 69 91 DC 00 D7 FE B8 00 06 68 D4 00 1E FD B8 00 37 AC DD 00 7C 15 00 00 7C 15 00 00 C2 4D 40 00 2D 6E 40 00 C9 74 40 00 F1 EF D4 00 73 6E 40 00 1F D2 CD 00 CA D1 CD 00 BE 3A D5 00 73 6E 40 00 86 39 CD 00 ° . . . . . . . , . . . S . 1 . E . A . f . d . 3 . 3 . Q . a . W . 5 . w . 6 . S . I . b . / . i . K . O . n . o . 2 . t . G . 6 . t . c . 6 . O . Q . i . E . t . s . l . n . p . E . W . E . w . = . . . 1 � ¤ . € € € € € € € € € € € € € € . . . . ! € , � . . . . . . . . . . . . . . . . á . . . ¦ M @ . . n @ . ~ t @ . + — Û . m € Ü . › Ñ Í . z : Õ . h 9 Í . Ô 9 Í . b � Ü . i ‘ Ü . × þ ¸ . . h Ô . . ý ¸ . 7 ¬ Ý . | . . . | . . . Â M @ . - n @ . É t @ . ñ ï Ô . s n @ . . Ò Í . Ê Ñ Í . ¾ : Õ . s n @ . † 9 Í . The culprit seems to be TBetFairApi.GetToken and here is the code: function TBetFairApi.GetToken: Boolean; var LJSONObject: TJSONObject; LJSONValue: TJSONValue; s:string; begin Result := False; FidHTTP := TidHTTP.Create(nil); FidHTTP.HTTPOptions := FidHTTP.HTTPOptions - [hoForceEncodeParams]; FidHTTP.Intercept := TIdLogFile.Create(FidHTTP); s:=ExtractFileName(ParamStr((0))); s:=Copy(s,1,Pos('.',s)-1); TIdLogFile(FidHTTP.Intercept).Filename := 'c:\' + s + '.log'; TIdLogFile(FidHTTP.Intercept).Active := true; FList := TStringList.Create; FIdSSL := TIdSSLIOHandlerSocketOpenSSL.Create; FIdSSL.SSLOptions.Method:=sslvTLSv1_2; FidHTTP.Request.Accept := 'application/json'; FidHTTP.Request.CustomHeaders.Clear; FidHTTP.Request.CustomHeaders.AddValue('X-Application', cBetfair_AppKey); FList.Clear; FList.Add('username=' + FUserID); FList.Add('password=' + FPassword); FidHTTP.Request.ContentType := 'application/x-www-form-urlencoded'; FidHTTP.HandleRedirects := true; {$IFDEF VER230} FidHTTP.IOHandler := FIdSSL; {$ENDIF} LJSONObject := TJSONObject.ParseJSONValue(FidHTTP.Post(URL_LOGIN, FList)) as TJSONObject; try if Assigned(LJSONObject) then begin LJSONValue := LJSONObject.{$IFDEF VER230}Get('token').JsonValue{$ELSE}Values['token']{$ENDIF}; if Assigned(LJSONValue) then begin FToken := LJSONValue.Value; Result := True; end; end; finally FreeAndNil(LJSONObject); end; FreeAndNil(FidHTTP); {$IFDEF VER230} FreeAndNil(FIdSSL); {$ENDIF} FreeAndNil(FList); end; There are 4 .Creates: FidHTTP := TidHTTP.Create(nil); FList := TStringList.Create; FIdSSL := TIdSSLIOHandlerSocketOpenSSL.Create; FidHTTP.Intercept := TIdLogFile.Create(FidHTTP); The first three are freed at the end of the procedure and TIdLogFile.Create(FidHTTP) should be freed automatically when FidHTTP is freed. I cannot see any memory leak here but obviously I am wrong. Can you see anything I cannot? Alberto
-
One more memory leak and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
Sure, here it is in attach. I just wanted to avoid to attach a minimal example every time. Test3.zip -
One more memory leak and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
Ok, I have also implemented QueryInterface, AfterConstruction, BeforeDestruction and NewInstance in my DataModule In this case, there are no leaks in both cases, with our without .AsSingleton. At this stage, I started implementing the other classes, one by one and .AsSingleton in my datamodule started making a difference when I arrived at the class TBetFairAPINGHorseFunctionSimulationBL TBetFairAPINGHorseFunctionSimulationBL = class(TInterfacedObject, ILBS_BetfairAPINGFunctionsBL) private FDM: IMainDMTEST; public constructor Create(aDM: IMainDMTEST); reintroduce; destructor Destroy; override; end; constructor TBetFairAPINGHorseFunctionSimulationBL.Create(aDM: IMainDMTEST); begin inherited create; FDM := aDM; end; destructor TBetFairAPINGHorseFunctionSimulationBL.Destroy; begin FDM := nil; inherited; end; I have added TBetFairAPINGHorseFunctionSimulationBL.Destroy and set FDM=nil in there but this destructor is never executed, don't know why as this class inherits from TInterfacedObject? As the last attempt, I have added a line at the end of the program to try to release the IMainDMTest at the very end of the application but the leak is still there. var FScalpingBL: IScalpingBL; Test: IMainDMTEST; begin RegisterTypes(GlobalContainer); Test := GlobalContainer.Resolve<IMainDMTEST>; FScalpingBL := globalcontainer.Resolve<IScalpingBL>; Test := nil; end. If I remove .AsSingleton when I resolve the interface then I have no more leaks but I have to keep .AsSingleton because this class holds/manages data and several classes have access to it. -
One more memory leak and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
Sorry I didn't explain properly. _AddRef and _Release are implemented in my example. It was the other procedures from Jeroen's example that have been left out as you advised. If I create the object as per your example above then there is no leak. I suppose the issue is in the way I resolve the interface in the Spring container. -
One more memory leak and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
I looked into TInterfacedObject again and implemented _AddRef and _Release in the same way, leaving out the remaining procedures, the example attached to this post is the updated minimum example. Unfortunately, I still have the same leaks. I started that thread. Now I know why I cannot have access to it any longer. Test2.zip -
One more memory leak and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
I have managed to make a minimal example that leaks. I will attach it here. I have found this article on how to make a TDataModule reference counting written by Jeroen Pluimers https://wiert.me/2009/08/10/delphi-using-fastmm4-part-2-tdatamodule-descendants-exposing-interfaces-or-the-introduction-of-a-tinterfaceddatamodule/ and tried to implement it in MainDMSimulation in the example. Despite that, the example is still leaking. I think is I am still doing something wrong when it comes to making TDataModule reference counting or in the way I resolve the interface in the Spring4D container (or maybe both). Test.zip -
Hello Everybody, I am looking for the equivalent of the Excel function LINEST in Delphi but I cannot find it. Do you know any library has it? Many thanks Alberto
-
One more memory leak and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
TBetFairApi.GetToken works perfectly now, thank you very much! Now I have to debug the rest because, you are right, there is another leak elsewhere. I will work on a minimal example. Thank you again, everybody. I have learnt a few new things ! -
One more memory leak and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
I did more investigation on the leaking instruction and found out that LJSONValue.Value; is UnicodeString. As FToken was a string I changed FToken into a UnicodeString but this didn't change anything. I don't know if this can help. -
One more memory leak and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
Hi Remy, I tried the code you suggests but I still have leaks. The following is the report: --------------------------------2020/6/24 16:32:52-------------------------------- A memory block has been leaked. The size is: 116 This block was allocated by thread 0x2D9C, and the stack trace (return addresses) at the time was: 404DA6 [System.pas][System][@GetMem$qqri][3454] 408BBB [System.pas][System][@NewUnicodeString$qqri][19030] 408DEC [System.pas][System][@UStrFromPWCharLen$qqrr20System.UnicodeStringpbi][19697] 40A0C9 [System.pas][System][@UStrCopy$qqrx20System.UnicodeStringii][24873] E5CAD3 [Data.DBXPlatform.pas][Data.DBXPlatform][Dbxplatform.TDBXStringBuffer.ToString$qqrv][697] E8E8BC [Data.DBXJSON.pas][Data.DBXJSON][Dbxjson.TJSONString.Value$qqrv][1541] E92948 [uBetFair.pas][uBetFair][TBetFairApi.GetToken$qqrv][238] E92E00 [uTokenBL.pas][uTokenBL][TTokenBL.GetToken$qqrv][30] E5B593 [Main.pas][Main][TMainForm.FormActivate$qqrp14System.TObject][402] 557ED9 [Vcl.Forms][Forms.TCustomForm.Activate$qqrv] 558F99 [Vcl.Forms][Forms.TCustomForm.CMActivate$qqrr27Winapi.Messages.TWMNoParams] 4B4930 [Vcl.Controls.pas][Vcl.Controls][Controls.TControl.WndProc$qqrr24Winapi.Messages.TMessage][7204] 76EAC431 [Unknown function at gapfnScSendMessage] 76EAC3EE [Unknown function at gapfnScSendMessage] 76EAC380 [Unknown function at gapfnScSendMessage] The block is currently used for an object of class: UnicodeString The allocation number is: 60670 and the following is the line 238 FToken := LJSONValue.Value; I am confused here. If I don't have to free TJSONValue why is there this line in the code you propose? finally LJSONValue.Free; end; What am I missing here? -
One more memory leak and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
I will answer your questions here below. 1) I didn't know about the FreeAndNil. I will google it and find out the details of when to use it and when not to. 2) FidHTTP, FList, FIdSSL are private variable of TBetFairApi. As these classes were used in two different procedures I declared this way to share them. No problem, declaring them locally will make the code more readable and maintainable. 3) This is very good advice indeed. I will follow it going forward 4) FToken is a private string which is used in a number of procedures in TBetFairApi. This is also linked to the TBetFairApi.Token property. The result of TBetFairApi.GetToken is a boolean because it was easier for me to do unit testing. I may change it in the future tho. 6) I think this is because this function comes from another version of Delphi hence the IFDEFs. I may change it in the future. 😎 FToken is UnicodeString now 5) I tried your code but it always gives me a leak on the line 235 which are the lines you suggested. UniqueString(FToken); or FToken := Trim(FToken+' '); here is the report --------------------------------2020/6/24 16:25:39-------------------------------- A memory block has been leaked. The size is: 116 This block was allocated by thread 0x2FA8, and the stack trace (return addresses) at the time was: 404DA6 [System.pas][System][@GetMem$qqri][3454] 408BBB [System.pas][System][@NewUnicodeString$qqri][19030] 4091AF [System.pas][System][InternalUniqueStringU$qqrr20System.UnicodeString][20569] E929AA [uBetFair.pas][uBetFair][TBetFairApi.GetToken$qqrv][235] E92E8C [uTokenBL.pas][uTokenBL][TTokenBL.GetToken$qqrv][30] E5B593 [Main.pas][Main][TMainForm.FormActivate$qqrp14System.TObject][402] 557ED9 [Vcl.Forms][Forms.TCustomForm.Activate$qqrv] 558F99 [Vcl.Forms][Forms.TCustomForm.CMActivate$qqrr27Winapi.Messages.TWMNoParams] 4B4930 [Vcl.Controls.pas][Vcl.Controls][Controls.TControl.WndProc$qqrr24Winapi.Messages.TMessage][7204] 76EAC431 [Unknown function at gapfnScSendMessage] 76EAC3EE [Unknown function at gapfnScSendMessage] 76EAC380 [Unknown function at gapfnScSendMessage] 76EAC431 [Unknown function at gapfnScSendMessage] 76EAC3EE [Unknown function at gapfnScSendMessage] 76EA4D0E [Unknown function at GetScrollBarInfo] -
One more memory leak and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
Here is the revised code: function TBetFairApi.GetToken: Boolean; var LJSONObject: TJSONObject; LJSONValue: TJSONValue; s:string; IdLogFile:TIdLogFile; begin try Result := False; FidHTTP := TidHTTP.Create(nil); FidHTTP.HTTPOptions := FidHTTP.HTTPOptions - [hoForceEncodeParams]; IdLogFile:=TIdLogFile.Create(FidHTTP); FidHTTP.Intercept := IdLogFile; s:=ExtractFileName(ParamStr((0))); s:=Copy(s,1,Pos('.',s)-1); TIdLogFile(FidHTTP.Intercept).Filename := 'c:\'+s+'.log'; TIdLogFile(FidHTTP.Intercept).Active := true; FList := TStringList.Create; FIdSSL := TIdSSLIOHandlerSocketOpenSSL.Create; FIdSSL.SSLOptions.Method:=sslvTLSv1_2; FidHTTP.Request.Accept := 'application/json'; FidHTTP.Request.CustomHeaders.Clear; FidHTTP.Request.CustomHeaders.AddValue('X-Application', cBetfair_AppKey); FList.Clear; FList.Add('username=' + FUserID); FList.Add('password=' + FPassword); FidHTTP.Request.ContentType := 'application/x-www-form-urlencoded'; FidHTTP.HandleRedirects := true; {$IFDEF VER230} FidHTTP.IOHandler := FIdSSL; {$ENDIF} LJSONObject := TJSONObject.ParseJSONValue(FidHTTP.Post(URL_LOGIN, FList)) as TJSONObject; // This is line 218 try if Assigned(LJSONObject) then begin LJSONValue := LJSONObject.{$IFDEF VER230}Get('token').JsonValue{$ELSE}Values['token']{$ENDIF}; try if Assigned(LJSONValue) then begin FToken := LJSONValue.Value; Result := True; end; finally FreeAndNil(LJSONValue); // I free the object as soon as I don't need any longer end; end; finally FreeAndNil(LJSONObject); end; finally FreeAndNil(IdLogFile); FreeAndNil(FidHTTP); {$IFDEF VER230} FreeAndNil(FIdSSL); {$ENDIF} FreeAndNil(FList); end; end; and this is the leak report from FastMM4 --------------------------------2020/6/23 21:33:53-------------------------------- FastMM has detected an attempt to call a virtual method on a freed object. An access violation will now be raised in order to abort the current operation. Freed object class: Data.DBXJSON.TJSONString Virtual method: Offset +16 Virtual method address: E8D644 The allocation number was: 60454 The object was allocated by thread 0xAD4, and the stack trace (return addresses) at the time was: 406E0F [System.pas][System][TObject.NewInstance$qqrv][13000] 40747E [System.pas][System][@ClassCreate$qqrpvzc][14164] E8E3E7 [Data.DBXJSON.pas][Data.DBXJSON][Dbxjson.TJSONString.$bctr$qqrx20System.UnicodeString][1410] E8FD6C [Data.DBXJSON.pas][Data.DBXJSON][Dbxjson.TJSONObject.ParseString$qqrpx28Data.Dbxjson.TJSONByteReaderpx26Data.Dbxjson.TJSONAncestor][2235] E8F78E [Data.DBXJSON.pas][Data.DBXJSON][Dbxjson.TJSONObject.ParseValue$qqrpx28Data.Dbxjson.TJSONByteReaderpx26Data.Dbxjson.TJSONAncestor][2010] E8F5F5 [Data.DBXJSON.pas][Data.DBXJSON][Dbxjson.TJSONObject.ParsePair$qqrpx28Data.Dbxjson.TJSONByteReaderpx24Data.Dbxjson.TJSONObject][1958] E8F476 [Data.DBXJSON.pas][Data.DBXJSON][Dbxjson.TJSONObject.Parse$qqrpx28Data.Dbxjson.TJSONByteReader][1892] E8F577 [Data.DBXJSON.pas][Data.DBXJSON][Dbxjson.TJSONObject.ParseObject$qqrpx28Data.Dbxjson.TJSONByteReaderpx26Data.Dbxjson.TJSONAncestor][1938] E8F7AA [Data.DBXJSON.pas][Data.DBXJSON][Dbxjson.TJSONObject.ParseValue$qqrpx28Data.Dbxjson.TJSONByteReaderpx26Data.Dbxjson.TJSONAncestor][2024] E8EE51 [Data.DBXJSON.pas][Data.DBXJSON][Dbxjson.TJSONObject.ParseJSONValue$qqrx25System.%DynamicArray$tuc%xixio][1666] 432D26 [System.SysUtils][Sysutils.TEncoding.GetBytes$qqrx20System.UnicodeString] E8EDF0 [Data.DBXJSON.pas][Data.DBXJSON][Dbxjson.TJSONObject.ParseJSONValue$qqrx25System.%DynamicArray$tuc%xio][1651] E8EED1 [Data.DBXJSON.pas][Data.DBXJSON][Dbxjson.TJSONObject.ParseJSONValue$qqrx20System.UnicodeString][1677] E92947 [uBetFair.pas][uBetFair][TBetFairApi.GetToken$qqrv][218] E92EE0 [uTokenBL.pas][uTokenBL][TTokenBL.GetToken$qqrv][30] The object was subsequently freed by thread 0xAD4, and the stack trace (return addresses) at the time was: 404DC2 [System.pas][System][@FreeMem$qqrpv][3502] 406E2D [System.pas][System][TObject.FreeInstance$qqrv][13006] 4074C9 [System.pas][System][@ClassDestroy$qqrp14System.TObject][14206] E8E455 [Data.DBXJSON.pas][Data.DBXJSON][Dbxjson.TJSONString.$bdtr$qqrv][1419] 406E73 [System.pas][System][TObject.Free$qqrv][13025] E929CE [uBetFair.pas][uBetFair][TBetFairApi.GetToken$qqrv][230] E92EE0 [uTokenBL.pas][uTokenBL][TTokenBL.GetToken$qqrv][30] E5B593 [Main.pas][Main][TMainForm.FormActivate$qqrp14System.TObject][402] 557ED9 [Vcl.Forms][Forms.TCustomForm.Activate$qqrv] 558F99 [Vcl.Forms][Forms.TCustomForm.CMActivate$qqrr27Winapi.Messages.TWMNoParams] 4B4930 [Vcl.Controls.pas][Vcl.Controls][Controls.TControl.WndProc$qqrr24Winapi.Messages.TMessage][7204] 7600C431 [Unknown function at gapfnScSendMessage] 7600C3EE [Unknown function at gapfnScSendMessage] 7600C380 [Unknown function at gapfnScSendMessage] 7600C431 [Unknown function at gapfnScSendMessage] The current thread ID is 0xAD4, and the stack trace (return addresses) leading to this error is: 406E73 [System.pas][System][TObject.Free$qqrv][13025] E8F12D [Data.DBXJSON.pas][Data.DBXJSON][Dbxjson.TJSONObject.$bdtr$qqrv][1762] 406E73 [System.pas][System][TObject.Free$qqrv][13025] E929F6 [uBetFair.pas][uBetFair][TBetFairApi.GetToken$qqrv][234] E92EE0 [uTokenBL.pas][uTokenBL][TTokenBL.GetToken$qqrv][30] E5B593 [Main.pas][Main][TMainForm.FormActivate$qqrp14System.TObject][402] 557ED9 [Vcl.Forms][Forms.TCustomForm.Activate$qqrv] 558F99 [Vcl.Forms][Forms.TCustomForm.CMActivate$qqrr27Winapi.Messages.TWMNoParams] 4B4930 [Vcl.Controls.pas][Vcl.Controls][Controls.TControl.WndProc$qqrr24Winapi.Messages.TMessage][7204] 7600C431 [Unknown function at gapfnScSendMessage] 7600C3EE [Unknown function at gapfnScSendMessage] 7600C380 [Unknown function at gapfnScSendMessage] 7600C431 [Unknown function at gapfnScSendMessage] 7600C3EE [Unknown function at gapfnScSendMessage] 76004D0E [Unknown function at GetScrollBarInfo] Current memory dump of 256 bytes starting at pointer address 7F2FEFC0: 94 B2 F1 00 80 80 80 80 80 80 80 80 80 80 80 80 A9 74 9A 96 80 80 80 80 00 00 00 00 61 E5 2F 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 EC 00 00 0F 6E 40 00 7E 74 40 00 6F CA E5 00 18 6E 40 00 7E 74 40 00 04 E4 E8 00 6C FD E8 00 8E F7 E8 00 F5 F5 E8 00 76 F4 E8 00 77 F5 E8 00 AA F7 E8 00 51 EE E8 00 26 2D 43 00 F0 ED E8 00 D4 0A 00 00 D4 0A 00 00 C2 4D 40 00 2D 6E 40 00 C9 74 40 00 66 6E 40 00 73 6E 40 00 3F E4 E8 00 73 6E 40 00 CE 29 E9 00 E0 2E E9 00 93 B5 E5 00 D9 7E 55 00 99 8F 55 00 30 49 4B 00 31 C4 00 76 EE C3 00 76 10 00 00 00 18 C3 E5 00 9F 4C 8D 7C 94 B2 F1 00 80 80 80 80 80 80 80 80 80 80 80 80 60 B3 72 83 80 80 80 80 00 00 00 00 80 B7 2F 7F 00 00 00 00 00 00 00 00 80 47 41 00 00 00 00 00 59 EC 00 00 A6 4D 40 00 0F 6E 40 00 7E 74 40 00 ” ² ñ . € € € € € € € € € € € € © t š – € € € € . . . . a å / � . . . . . . . . . . . . . . . . ' ì . . . n @ . ~ t @ . o Ê å . . n @ . ~ t @ . . ä è . l ý è . Ž ÷ è . õ õ è . v ô è . w õ è . ª ÷ è . Q î è . & - C . ð í è . Ô . . . Ô . . . Â M @ . - n @ . É t @ . f n @ . s n @ . ? ä è . s n @ . Î ) é . à . é . “ µ å . Ù ~ U . ™ � U . 0 I K . 1 Ä . v î Ã . v . . . . . Ã å . Ÿ L � | ” ² ñ . € € € € € € € € € € € € ` ³ r ƒ € € € € . . . . € · / � . . . . . . . . € G A . . . . . Y ì . . ¦ M @ . . n @ . ~ t @ . I put a breakpoint on the line FreeAndNil(IdLogFile) and LJSONValue is nil -
One more memory leak and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
Get('token') return a TJSONPair object I tried to add the following after having retrieved the value: LJSONObject.Free; LJSONValue.Free; LJSONObject.Get('token').Free; LJSONObject.Get('token').JsonValue.Free; but all of them made things worse -
One more memory leak and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
The line 222 in TBetFairApi.GetToken is if Assigned(LJSONValue) I tried FreeAndNil(LJSONValue) after having retrieved the value but this generates additional errors. I know and I appreciate that. -
One more memory leak and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
Sorry, Delphi XE2 I have added it to my profile now. -
I have fixed all the leaks related to units I have developed but now I ran into the following: --------------------------------2020/6/21 15:43:36-------------------------------- A memory block has been leaked. The size is: 36 This block was allocated by thread 0x26AC, and the stack trace (return addresses) at the time was: 404DA6 [System.pas][System][@GetMem$qqri][3454] 408BBB [System.pas][System][@NewUnicodeString$qqri][19030] 409E37 [System.pas][System][@UStrSetLength$qqrr20System.UnicodeStringi][24243] 409E8E [System.pas][System][@UStrCat$qqrr20System.UnicodeStringx20System.UnicodeString][24326] C2B610 [IdURI.pas][IdURI][TIdURI.GetPathAndParams$qqrv][672] C60593 [IdHttp.pas][IdHTTP][TIdCustomHTTP.PrepareRequest$qqrp21Idhttp.TIdHTTPRequest][1828] C635FE [IdHttp.pas][IdHTTP][TIdCustomHTTP.DoRequest$qqrx20System.UnicodeString20System.UnicodeStringp22System.Classes.TStreamt3psxi][3156] C1E193 [IdIOHandlerStack.pas][IdIOHandlerStack][TIdIOHandlerStack.Connected$qqrv][244] C5DE5B [IdHttp.pas][IdHTTP][TIdCustomHTTP.Post$qqr20System.UnicodeStringp22System.Classes.TStreamt2][812] C5E6E5 [IdHttp.pas][IdHTTP][TIdCustomHTTP.Post$qqr20System.UnicodeStringp23System.Classes.TStringsp22System.Classes.TStream52System.%DelphiInterface$t24Idglobal.IIdTextEncoding%][1067] C5E804 [IdHttp.pas][IdHTTP][TIdCustomHTTP.Post$qqr20System.UnicodeStringp23System.Classes.TStrings52System.%DelphiInterface$t24Idglobal.IIdTextEncoding%][1084] The block is currently used for an object of class: UnicodeString The allocation number is: 58517 Current memory dump of 256 bytes starting at pointer address 7F35D810: B0 04 02 00 01 00 00 00 0A 00 00 00 2F 00 61 00 70 00 69 00 2F 00 6C 00 6F 00 67 00 69 00 6E 00 00 00 E1 8F B9 72 80 80 00 00 00 00 F1 D8 35 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 E3 00 00 A6 4D 40 00 0F 6E 40 00 55 CC 40 00 7E 74 40 00 8E AA EB 00 CB 5E 73 00 09 9A EC 00 C3 FC ED 00 CB 2B 8D 00 51 64 8F 00 55 18 7B 00 AC 26 00 00 AC 26 00 00 C2 4D 40 00 2D 6E 40 00 C9 74 40 00 94 AB EB 00 BB CC 40 00 C7 CB 40 00 D5 A7 40 00 C5 A6 40 00 E3 6E 40 00 26 6E 40 00 C9 74 40 00 20 00 00 00 90 A8 EB 00 E8 0B 67 89 94 A2 F1 00 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 17 F4 98 76 80 80 80 80 00 00 00 00 C1 DD 35 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 17 E3 00 00 A6 4D 40 00 0F 6E 40 00 55 CC 40 00 ° . . . . . . . . . . . / . a . p . i . / . l . o . g . i . n . . . á � ¹ r € € . . . . ñ Ø 5 � . . . . . . . . . . . . . . . . H ã . . ¦ M @ . . n @ . U Ì @ . ~ t @ . Ž ª ë . Ë ^ s . . š ì . Ã ü í . Ë + � . Q d � . U . { . ¬ & . . ¬ & . . Â M @ . - n @ . É t @ . ” « ë . » Ì @ . Ç Ë @ . Õ § @ . Å ¦ @ . ã n @ . & n @ . É t @ . . . . � ¨ ë . è . g ‰ ” ¢ ñ . € € € € € € € € € € € € € € € € € € € € € € € € € € € € . ô ˜ v € € € € . . . . Á Ý 5 � . . . . . . . . . . . . . . . . . ã . . ¦ M @ . . n @ . U Ì @ . I haven't developed or amended any of the units mentioned in the report. I strongly doubt there is a leak in the units mentioned in the report as they are either part of the VCL or part of Indy but at the same time, I don't know where I can find the leak in my code. Can anybody help me? Many thanks Alberto
-
Again with memory leaks and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
Yes, the following is the destructor now destructor TBetFairApi.Destroy; begin //if Assigned(FList) then // FList.Free; // if Assigned(FidHTTP) then // FidHTTP.Free; // {$IFDEF VER230} // if Assigned(FIdSSL) then // // FIdSSL.Free; // {$ENDIF} inherited Destroy; end; before the code was not commented on. -
Again with memory leaks and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
I moved FreeAndNil(IdHttp) from the Destructor to the procedure where IdHttp is created and no more leaks. This suggests a bad design of the class (I made it) and I will look into that again because it seems the destructor is not invoked. I double-checked and in the declaration section and the destructor has override in it, correctly. -
Again with memory leaks and FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
This is something I am rather sure not to be the case as I avoid exits as much as possible. I will check these too though. I am running the application step by step and see the objects created at run time and see where/if they are released. Thanks everybody for your help Alberto -
I have started removing memory leaks in my application and installed and configured FastMM4. I ran the application and the following is an excerpt from the memory leaks report. --------------------------------2020/6/20 21:24:00-------------------------------- A memory block has been leaked. The size is: 100 This block was allocated by thread 0x13C4, and the stack trace (return addresses) at the time was: 404DA6 [System.pas][System][@GetMem$qqri][3454] 406E0F [System.pas][System][TObject.NewInstance$qqrv][13000] 40747E [System.pas][System][@ClassCreate$qqrpvzc][14164] 45926E [System.Classes.pas][System.Classes][Classes.TStringList.$bctr$qqrv][6408] EAF697 [uBetFairAPIHorseHelperBL.pas][uBetFairAPIHorseHelperBL][TBetFairAPIHorseHelperBL.ResetEventID$qqrv][921] EAED20 [uBetFairAPIHorseHelperBL.pas][uBetFairAPIHorseHelperBL][TBetFairAPIHorseHelperBL.ListEvents$qqr20System.UnicodeString][611] D4C0EB [DBAccess][TCustomDADataSet.GetRecordCount$qqrv] E92D6A [uTokenBL.pas][uTokenBL][TTokenBL.GetTokenID$qqrv][34] E5A73D [Main.pas][Main][TMainForm.btnFindRacesClick$qqrp14System.TObject][190] E5B5C5 [Main.pas][Main][TMainForm.FormActivate$qqrp14System.TObject][418] 557E7D [Vcl.Forms][Forms.TCustomForm.Activate$qqrv] The block is currently used for an object of class: System.Classes.TStringList The allocation number is: 199660 Current memory dump of 256 bytes starting at pointer address 7F322C00: 2C A7 44 00 00 00 00 00 00 00 00 00 40 B7 A9 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 88 40 34 7F 01 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FC CD 79 80 80 80 80 80 80 80 80 00 00 00 00 01 33 32 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 99 E6 0B 00 A6 4D 40 00 0F 6E 40 00 7E 74 40 00 6E 92 45 00 18 6E 40 00 7E 74 40 00 2D 37 D7 00 CA 53 D7 00 A3 11 DA 00 93 E9 D3 00 A8 4F D4 00 C4 13 00 00 C4 13 00 00 C2 4D 40 00 2D 6E 40 00 C9 74 40 00 23 8B 45 00 73 6E 40 00 8E 37 D7 00 73 6E 40 00 67 54 D7 00 ED 11 DA 00 73 6E 40 00 EB 37 CD 00 5C 00 00 00 2C A7 44 00 26 3A 59 8A 94 A2 F1 00 80 80 80 80 80 80 80 80 80 80 80 80 , § D . . . . . . . . . @ · © � . . . . . . . . . . . . . . . . . . . . . . . . . . . . ˆ @ 4 � . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ÿ ü Í y € € € € € € € € . . . . . 3 2 � . . . . . . . . . . . . . . . . ™ æ . . ¦ M @ . . n @ . ~ t @ . n ’ E . . n @ . ~ t @ . - 7 × . Ê S × . £ . Ú . “ é Ó . ¨ O Ô . Ä . . . Ä . . . Â M @ . - n @ . É t @ . # ‹ E . s n @ . Ž 7 × . s n @ . g T × . í . Ú . s n @ . ë 7 Í . \ . . . , § D . & : Y Š ” ¢ ñ . € € € € € € € € € € € € As this is the first time I use FastMM4 I don't know how to start to fix the leaks. Can somebody point out a tutorial that starts from scratch on this topic? Many thanks Alberto
-
Fixing memory leaks with FastMM4
Alberto Paganini replied to Alberto Paganini's topic in RTL and Delphi Object Pascal
Thank you very much for your answer, Alexander. Is there anything on the web that teaches how to read the report? -
LINEST function
Alberto Paganini replied to Alberto Paganini's topic in Algorithms, Data Structures and Class Design
I have found here https://support.office.com/en-gb/article/linest-function-84d7d0d9-6e50-4101-977a-fa7abf772b6d the formula and I was able to implement my solution: program Project3; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; function Linest(x, y: array of Double): Double; var AverageX, AverageY: Double; Total: Double; I: Integer; XMinusAverageX: Double; YMinusAverageY: Double; XMinusAverageXSquare: Double; XMinusAverageXByYMinusAverageY: Double; TotalXMinusAverageXSquare: Double; TotalXMinusAverageXByYMinusAverageY: Double; begin Total := 0; for I := 0 to Length(x) - 1 do Total := Total + x[I]; AverageX := Total / Length(x); Total := 0; for I := 0 to Length(y) - 1 do Total := Total + y[I]; AverageY := Total / Length(y); TotalXMinusAverageXSquare := 0; TotalXMinusAverageXByYMinusAverageY := 0; for I := 0 to Length(x) - 1 do begin XMinusAverageX := x[I] - AverageX; YMinusAverageY := y[I] - AverageY; XMinusAverageXSquare := Sqr(XMinusAverageX); XMinusAverageXByYMinusAverageY := XMinusAverageX * YMinusAverageY; TotalXMinusAverageXSquare := TotalXMinusAverageXSquare + XMinusAverageXSquare; TotalXMinusAverageXByYMinusAverageY := TotalXMinusAverageXByYMinusAverageY + XMinusAverageXByYMinusAverageY; end; Result := TotalXMinusAverageXByYMinusAverageY / TotalXMinusAverageXSquare; end; const ArrayDimension = 14; var x, y: array of Double; I: Integer; aResult: Double; begin SetLength(x, ArrayDimension); for I := 0 to Length(x) - 1 do x[I] := I; SetLength(y, ArrayDimension); y[0] := 184.45; y[1] := 134.71; y[2] := 157.16; y[3] := 168.63; y[4] := 219.83; y[5] := 247.9; y[6] := 247.37; y[7] := 247.37; y[8] := 343.45; y[9] := 570.45; y[10] := 558.21; y[11] := 559.39; y[12] := 559.39; y[13] := 559.39; aResult := Linest(x, y); end. This is just a simplification of the function because LINEST can accept more parameters but this is what I needed. -
Hi Uwe, Does it work for XE2 ?