You create one stringlist
6. sa := TStringList.Create;
Then you add values to it:
7. sa.Add('1');
8. sa.Add('2');
then you set the length of the array:
9. SetLength(sb,Length(sb)+1);
you set the first entry of the array to sa
10. sb[0] := sa;
then you clear that same sa stringlist (all values cleared from that list):
11. sa.Clear;
then you add two values to sa:
12. sa.Add('3');
13. sa.Add('4');
then you 'expand' the array again to make room for...
14. SetLength(sb,Length(sb)+1);
... yet another entry of the same sa stringlist class.
15. sb[1] := sa;
1. Storing a stringlist into an array does not automagically creates a copy for you
2. Using the same reference to the same stringlist means that you are still manipulating that same stringlist (and thus its contents).
PS: you changed the code so my analyses does not match your code accurately anymore.