delphi - Access Violation in TDictionary<Variant, Record> -


i wrote simple class test tdictionary<> class in delphi xe8.

when try show records added, brings me access violation error, don't understand why?

here class

unit unit3;  interface   uses   classes, system.sysutils, system.types, rest.types, system.json, data.bind.components,   system.regularexpressions, system.variants,   generics.collections, fmx.dialogs {$ifdef debug}, codesitelogging{$endif};  type    taarray2 = class;    ptrec=^trec;    trec = class   public     key : variant;     isrequired : boolean;     value : variant;     oldvalue : variant;     json : string;     items : taarray2;     procedure add(key : variant ; value: trec);   end;     taarray2 = class(tdictionary<variant, trec>)    private      function get(index: variant): trec;    public      destructor destroy; override;      procedure add(key : variant ; value: trec);      property items[cle : variant]: trec read get; default;    end;  implementation  procedure trec.add(key : variant ; value: trec); begin   if not(assigned(items))     self.items := taarray2.create;   items.add( key, value);   showmessage(inttostr(items.count)); // show 1 means items instanciate , contain proper data end;  function taarray2.get(index: variant): trec; begin   result := inherited items[index] end;  end. 

then i'm using code test : (a form 1 tbutton , 1 tmemo)

procedure tform1.showassocarray2(aaa : taarray2 ; level : integer); var   s : string;   myrec : trec; begin   myrec in aaa.values   begin     fillchar(s, level * 4, ' ');     memo1.lines.add(s + string(myrec.key) + ' = ' + string(myrec.value));     if myrec.items.count > 0  // error here       showassocarray2(myrec.items, level + 1);   // recursive childrens   end; end;  procedure tform1.button4click(sender: tobject); var   mylist : taarray2;   myrec : trec;   : integer; begin   mylist := taarray2.create;   := 0 9   begin     myrec := trec.create;     myrec.value := 'value_' + inttostr(i);     myrec.key := 'no_' + inttostr(i);     mylist.add(myrec.key, myrec);   end;   // subitem   myrec := trec.create;   myrec.value := 'test' + inttostr(i);   myrec.key := 'test' + inttostr(i);   mylist.items['no_3'].add('extra', myrec);    memo1.lines.add('nb of record : ' + inttostr(mylist.count));    showassocarray2(mylist, 0);  end; 

i tried many way : myrec.items.count or myrec.values.count or myrec.items.values.count... have error don't understand why?

this stripped version executes:

program project20;  {$apptype console}  {$r *.res}  uses   system.sysutils,generics.collections,strutils;   type   taarray2 = class;    trec = class   public     key : variant;     value : variant;     items : taarray2;     procedure add(key : variant ; value: trec);   end;     taarray2 = class(tdictionary<variant, trec>)    private      function get(index: variant): trec;    public      destructor destroy; override;      //procedure add(key : variant ; value: trec);      property items[cle : variant]: trec read get; default;    end;  procedure trec.add(key : variant ; value: trec); begin   if not(assigned(items))     self.items := taarray2.create;   items.add( key, value);   writeln(inttostr(items.count)); // show 1 means items instanciate , contain proper data end;  destructor taarray2.destroy; begin    inherited; end;  function taarray2.get(index: variant): trec; begin   result := inherited items[index] end;  procedure showassocarray2(aaa : taarray2 ; level : integer); var   s : string;   myrec : trec; begin   s := dupestring(' ',level * 4);   myrec in aaa.values   begin     writeln(s + string(myrec.key) + ' = ' + string(myrec.value));     if assigned(myrec.items) // <-- test if items assigned      if myrec.items.count > 0        showassocarray2(myrec.items, level + 1);   // recursive childrens   end; end;  var   mylist : taarray2;   myrec : trec;   : integer; begin   mylist := taarray2.create;   := 0 9   begin     myrec := trec.create;     myrec.value := 'value_' + inttostr(i);     myrec.key := 'no_' + inttostr(i);     mylist.add(myrec.key, myrec);   end;   // subitem   myrec := trec.create;   myrec.value := 'test' + inttostr(i);   myrec.key := 'test' + inttostr(i);   mylist.items['no_3'].add('extra', myrec);    writeln('nb of record : ' + inttostr(mylist.count));    showassocarray2(mylist, 0);   readln; end. 

the call fillchar() replaced dupestring(), since no memory allocated string before fillchar().

there test assigned(myrec.items) resolves case when items unassigned, which cause of access violation.

this executes, have not analyzed if result want. don't forget make sure there no memory leaks well.

the printout:

1 nb of record : 10 no_4 = value_4 no_3 = value_3     test10 = test10 no_9 = value_9 no_7 = value_7 no_8 = value_8 no_1 = value_1 no_2 = value_2 no_5 = value_5 no_0 = value_0 no_6 = value_6 

Comments

Popular posts from this blog

java - Spring Data JPA: Why findOne(id) executing delete query internally? -

python - Mongodb How to add addtional information when aggregating? -

java - Incorrect order of records in M-M relationship in hibernate -