Dynamic Array in System Verilog?

class ABC;
rand  logic [3:0]data[];
rand  logic [4:0]addr;
  rand  logic [3:0]length;
  
  constraint radom 
  {
    length == data.size();
    solve length before data;
  }
  
endclass

module tb();
  initial
    begin
      ABC m;
      repeat (3)
        begin
      m=new();
          $display("-----------------------------------------------------");
          $display("AB = %0p \t %0d \t %0d \t %0d",m.data, m.addr, m.length, m.data.size());
      m.randomize();
      
          $display("AB = %0p \t %0d \t %0d \t %0d ",m.data, m.addr, m.length, m.data.size());
           $display("-----------------------------------------------------");
        end
    end
endmodule


//Output

AB = '{} x x 0
AB = '{'h8, 'hd, 'h2, 'h4, 'h9, 'h5, 'h4, 'h2, 'hc, 'h5, 'h0, 'h2, 'h4} 25 13 13


AB = '{} x x 0
AB = '{'h3, 'h4, 'h5, 'hc, 'h7, 'h9, 'h8, 'h9, 'h4, 'hf, 'hb, 'h9, 'h3, 'h7, 'ha} 7 15 15


AB = '{} x x 0
AB = '{'hb, 'h1, 'h0, 'h0, 'h1} 11 5 5

//My Doubt here is, The dynamic array is created and the size of the dynamic array is 0 before randomization but after the randomization
the size of the dynamic array is changed as per the constraint specified. How does the size is changing after once the memory allocation is done.

In reply to Arun_Rajha:
Per 180’2017: 18.4 Random variables
The size of a dynamic array or queue declared as rand or randc can also be constrained. In that case, the array shall be resized according to the size constraint, and then all the array elements shall be randomized. The array size constraint is declared using the size method. For example:

rand bit [7:0] len;
rand integer data[];
constraint db { data.size == len; }

The variable len is declared to be 8 bits wide. The randomizer computes a random value for the len variable in the 8-bit range of 0 to 255 and then randomizes the first len elements of the data array.
When a dynamic array is resized by randomize(), the resized array is initialized (see 7.5.1) with the original array. When a queue is resized by randomize(), elements are inserted or deleted (see 7.10.2.2 and 7.10.2.3) at the back (i.e., right side) of the queue as necessary to produce the new queue size; any new elements inserted take on the default value of the element type. That is, the resize grows or shrinks the array. This is significant for a dynamic array or queue of class handles. randomize() does not allocate any class objects. Up to the new size, existing class objects are retained and their content randomized. If the new size is greater than the original size, each of the additional elements has a null value requiring no randomization.
In resizing a dynamic array or queue by randomize() or new, the rand_mode of each retained
element is preserved and the rand_mode of each new element is set to active.
If a dynamic array’s size is not constrained, then the array shall not be resized and all the array elements shall be randomized.
— An object handle can be declared rand, in which case all of that object’s variables and constraints are solved concurrently with the variables and constraints of the object that contains the handle.
Randomization shall not modify the actual object handle. Object handles shall not be declared
randc.
— An unpacked structure can be declared rand, in which case all of that structure’s random members are solved concurrently using one of the rules listed in this subclause. Unpacked structures shall not be declared randc. A member of an unpacked structure can be made random by having a rand or randc modifier in the declaration of its type.
For example:

class packet;
typedef struct {
randc int addr = 1 + constant;
int crc;
rand byte data [] = {1,2,3,4};
} header;
rand header h1;
endclass
packet p1=new;

— Unpacked unions shall not be declared rand or randc.
— Packed tagged unions shall not be declared rand or randc.
— A packed untagged union can be declared rand or randc, in which case that union is treated as an integral type. Members of packed untagged unions shall not have a random modifier.
— A packed structure can be declared rand or randc, in which case that structure is treated as an integral type. Members of packed structures shall not have a random modifier.
— If a rand variable of packed structure or packed untagged union type has a member of enum type, the rules in 18.3 restricting the random values of an enum variable shall not apply to that member.
For example:

typedef enum bit [1:0] { A=2'b00, B=2'b11 } ab_e;
typedef struct packed {
ab_e ValidAB;
} VStructEnum;
typedef union packed {
ab_e ValidAB;
} VUnionEnum;

When randomizing a variable of type ab_e, the solver can only select a random value of 2’b00 or 2’b11 (A or B, respectively). However, when randomizing a variable of type VStructEnum or
VUnionEnum, the solver can select 2’b00, 2’b01, 2’b10 or 2’b11.