Pepito Gomiz
Pepito Gomiz

Reputation: 59

TDictionary using pointers

Say that I have the following record:

   type
     TTest = record
       test1 : TTest1;
       test2 : TTest2;
       test3 : TTest3;
   end;
   pTTest = ^TTest;
   TDictestDictionary = TDictionary<integer,pTTest>;
    testDictionary : TDictestDictionary 

Will it be sufficient to write

   testDictionary := TDictionary<integer,pTTest>.Create;

and then add the items like:

   testDictionary.AddOrSetValue(1,pValue);

or need to initialize pValue ?

But then what happens when:

   GetMem(pValue, Value);
   testDictionary.AddOrSetValue(1,pValue);
   FreeMem(pValue);

will the items remove the data pointed by pValue ?

Please Help

Also, on the same line of thought, can I have something like this:

Type
  myClass = class(TObject)

  private
    FTest : TDictestDictionary ;

 public 
   property propFTest : TDictestDictionary  read getFTest() write setFTest()

but then how I write getFTest() setFTest()

Help. Thank you

Upvotes: 0

Views: 812

Answers (2)

Jens Borrisholt
Jens Borrisholt

Reputation: 6402

I would agree David. I see no need for pointers here. Use a class and a TObjectDictionary then you can create as many views as you want and memory management is still easy: One TObjectDictionary owns the classes the other TObjectDictionary or TList<>are just views presending your data different.

Here is a unit ment for inspiration.

unit TestDictionaryU;

interface

uses
  System.Generics.Collections;

type
  TTest1 = class
  end;

  TTest2 = class
  end;

  TTest3 = class
  end;

  TTest = class
    test1: TTest1;
    test2: TTest2;
    test3: TTest3;
    constructor Create;
    destructor Destroy; override;
  end;

  TTestDictonary = class(TObjectDictionary<Integer, TTest>)
  public
    constructor Create;
    function AddTest : TTest;
  end;

implementation

{ TTest }

constructor TTest.Create;
begin
  inherited;
  test1 := TTest1.Create;
  test2 := TTest2.Create;
  test3 := TTest3.Create
end;

destructor TTest.Destroy;
begin
  test1.Free;
  test2.Free;
  test3.Free;
  inherited;
end;

{ TTestDictonary }

function TTestDictonary.AddTest: TTest;
begin
  Result := TTest.Create;
end;

constructor TTestDictonary.Create;
begin
  inherited Create([doOwnsValues]);
end;

end.

Upvotes: 0

David Heffernan
David Heffernan

Reputation: 613013

If you really want to store pointers in your container, then you will need to allocate the memory at some point. If you deallocate the memory when the container still contains a reference to that memory, then the container's reference is useless. It is known as a stale pointer. Invariably, holding stale pointers means your code is defective.

There seems to me to be no need to use pointers here. You can declare the dictionary like this:

TDictionary<Integer, TTest>

That container holds copies of your records, and so manages the lifetime automatically.

Upvotes: 2

Related Questions