Recent

Author Topic: Newbie problem with TDictionary  (Read 629 times)

phunkz

  • Newbie
  • Posts: 2
Newbie problem with TDictionary
« on: November 02, 2024, 11:40:44 pm »
Hi there,

using fpc 3.2.2 in ide lazarus 3.4 and today updated to 3.6 (no change in behaviour) under win 10 in a Virtualbox VM with enough free ram

I desperately want to create a global Database object which holds data in a key-value-store using a Tdictionary.
Later on i want to use a real database for persistent storage. but for now a TDict should do the job.
Now i have created a unit which defines a class TDatabase with a private KeyValueDict: TDictionary , its methods constructor create/get/store/destructor destroy/and  instantiates a variable GlobalDatastore

But after "create" it seems, while stepping with the debugger, that the destructor is directly called afterwards which i dont understand.
is anything wrong with the method "create"?
Any access via "get" to KeyValueDict throws a read memory error. Compiling is fine but lots of warnings making me nervous.
Ive used the some AIs and the search function in this forum but could not find a solution
Ive added C:\lazarus\fpc\3.2.2\source\packages\rtl-generics\src to the path. Without this stepping into TDictionary was not possible.
Any Ideas?
I'm a total newbie to pascal but not for  programming in other languages so its possible that ive done some pretty dumb mistakes.
Many thanks in advance.

Code: Pascal  [Select][+][-]
  1. unit TT_database;
  2. // shared object
  3.  
  4. {$mode Delphi}  {$H+}
  5.  
  6. interface
  7.  
  8. uses
  9.   Classes, SysUtils, Generics.Collections, Variants;
  10.  
  11. type
  12.   TDataBase = class
  13.   private
  14.     KeyValueDict: TDictionary<string, Variant>;
  15.   public
  16.     constructor Create;
  17.     destructor Destroy; override;
  18.     procedure Store(const Key: string; const Value: Variant);
  19.     function Get(const Key: string): Variant;
  20.   end;
  21.  
  22. var
  23.   GlobalDatastore: TDataBase;
  24.  
  25. implementation
  26.  
  27. { TDataBase }
  28.  
  29. constructor TDataBase.Create;
  30. begin
  31.   KeyValueDict := TDictionary<string, Variant>.Create;
  32. end;
  33.  
  34. destructor TDataBase.Destroy;
  35. begin
  36.   KeyValueDict.Free;
  37.   inherited;
  38. end;
  39.  
  40. procedure TDataBase.Store(const Key: string; const Value: Variant);
  41. begin
  42.   KeyValueDict.Add(Key, Value);
  43. end;
  44.  
  45. function TDataBase.Get(const Key: string): Variant;
  46. begin
  47.   if KeyValueDict.ContainsKey(Key) then
  48.     Result := KeyValueDict[Key]
  49.   else
  50.     Result := Null; // Verwende Null anstelle eines leeren Strings für Variant
  51. end;
  52.  
  53. initialization
  54.   GlobalDatastore := TDataBase.Create;
  55.  
  56. finalization
  57.   GlobalDatastore.Destroy;
  58.  
  59. end.  


silvercoder70

  • Jr. Member
  • **
  • Posts: 88
    • Tim Coates
Re: Newbie problem with TDictionary
« Reply #1 on: November 03, 2024, 02:59:12 am »
Hi,

I have used your code exactly as is and it actually worked for me and behind a button put code ...

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   s: string;
  4. begin
  5.   GlobalDatastore.Store('a', '1');
  6.  
  7.   s := GlobalDatastore.Get('a');
  8.   showMessage(s);
  9. end;      
  10.  

Please keep in mind I am using the 4.0RC1 and FPC 3.2.2.

As a side-note I did set breakpoints in all of your functions/methods as well. What versions are you using?
Explore the beauty of modern Pascal programming with Delphi & Free Pascal - https://www.youtube.com/@silvercoder70

Thaddy

  • Hero Member
  • *****
  • Posts: 16138
  • Censorship about opinions does not belong here.
Re: Newbie problem with TDictionary
« Reply #2 on: November 03, 2024, 08:04:12 am »
Your code is a bit, well, over the top for what you actually mean.
Maybe you can do it like this:
Code: Pascal  [Select][+][-]
  1. unit mydatab;
  2. {$mode delphi}
  3. interface
  4. uses
  5.   Generics.Collections; // that is all you need
  6.  
  7. type
  8.   TYourDatabase = TDictionary<string, Variant>;
  9. var
  10.   GlobalDatastore: TYourDatabase;
  11.  
  12. implementation
  13.  
  14. initialization
  15.   GlobalDatastore := TYourDatabase.Create;
  16.  
  17. finalization
  18.   GlobalDatastore.Free;
  19. end.

I would not call your data store TDatabase, since that is an existing and often used class.
I also would not use store and get if all they do is calling add and retrieve, so I removed that.

Above unit is tested and working.
« Last Edit: November 03, 2024, 08:57:57 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

phunkz

  • Newbie
  • Posts: 2
Solved: Newbie problem with TDictionary
« Reply #3 on: November 04, 2024, 02:40:01 am »
Thanks to both,

working on your tipps, especially on the naming conventions,
i found the error, really dumb as previously announced...

I had an identically named local variable in the calling unit...






 

TinyPortal © 2005-2018