0

Jagged Array in C# is typical 1 dimensional array ,Array always needs length to be initialized. But how come references of arrays which do not have length initialized, are holding inside a jagged array ? How memory locations are allocated for those referenced arrays ?

            int[][] arr = new int[2][];

            for (int i = 1; i <= 2; i++)
            {
                arr[i-1] = new int[i * 5];
                for (int j = 0; j < i*5; j++)
                {
                    arr[i-1][j] = j;
                }
            }
          

            for (int i = 0; i < arr.Length; i++)
            {
                Console.Write("Element({0}): ", i);

                for (int j = 0; j < arr[i].Length; j++)
                {
                    Console.Write("{0}{1}", arr[i][j], j == (arr[i].Length - 1) ? "" : " ");
                }
                Console.WriteLine();
            }
            Console.WriteLine(arr.Length);
            Console.WriteLine(arr.Rank);
  • You create the inner arrays with `new int[i*5];`. At that point the array is allocated in memory (heap) like any other array (or object). What exactly are you struggling with? Keep in mind that array types are reference types. – Progman Nov 27 '20 at 22:12
  • Does this answer your question? [Memory allocation of Jagged arrays in C# vs 2d arrays memory allocation in C++](https://stackoverflow.com/questions/48605840/memory-allocation-of-jagged-arrays-in-c-sharp-vs-2d-arrays-memory-allocation-in) – Progman Nov 27 '20 at 22:14
  • @Progman thanks for replying. I just wanted to know , while defining array like this int[] arr=new int[]; this line will give me error unless I mention the size or use object initializer pattern without mentioning size . For Jagged array , how compiler knows the size ? array memory allocation is static . then how its getting possible for CLR to insert values at runtime without knowing the size? – Debashish Saha Nov 27 '20 at 22:22
  • 1
    The compiler doesn't need to know the size of the deeper levels. A jagged array is an array of arrays. The second level arrays are just references to an array. These references can be set later to a new array of any size. This does not however affect the size of these references in the top level array; they still remain references and as such have the same size. They simply now refer to a specific amount of memory on the heap. – Jonathan Willcock Nov 27 '20 at 22:33
  • 1
    You allocate the parent array. (like you normally would), Then you have to allocate each sub array, just like any other array. Its just an array of arrays, no magic – TheGeneral Nov 27 '20 at 22:41
  • @JonathanWillcock thanks for replying. I am assuming by specific amount of memory , you are mentioning 4Byte * size of array right ? But these referenced array does not have size . Thats where my doubt is . In books , I read that array memory allocation is statc . But here it seems , these references arrays are internally implemented as dynamic . – Debashish Saha Nov 27 '20 at 22:53
  • @TheGeneral , I dont think you are getting my point . Array allocation is static . that means CLR needs to know size before it initializes and accordingly allocates memory first . in jagged array , the refereced arrays do nt have any size . How CLR handle this unless these are dynamically implemented internally. I hope I am clear with my doubt . – Debashish Saha Nov 27 '20 at 22:56
  • You are completely overthinking this. Nothing is allocated until you allocate it – TheGeneral Nov 27 '20 at 23:26

2 Answers2

1

int[][] arr = new int[2][] only creates an outer array of empty references to inner arrays. The memory allocated is the number of references times single reference size. The outer array is stored in a single memory block and its values default to null.

The actual inner arrays storing int elements are not yet there. You need to create them explicitly (as you do in your example) with the size specification.

The inner arrays are not necessarily stored in a single memory block. This might have some performance impications, but it allows for different sizes of the actual (inner) arrays.

SzybkiDanny
  • 204
  • 2
  • 11
0

This is how memory is allocated in C#

int[][] array = new int[10][];
array[0] = new int[] { 1, 2, 3 };

If you look at the memory layout of array and array[0] you see the following

Address     Value     Notes
0x033B23F8  7179882C  (internal descriptor)
0x033B23FC  0000000a  =10 (array length)
0x033B2400  033B242C  ->(address of array[0], see * below)
0x033B2404  00000000  ->null
0x033B2408  00000000  ->null  
0x033B240C  00000000  ->null  
0x033B2410  00000000  ->null  
0x033B2414  00000000  ->null  
0x033B2418  00000000  ->null  
0x033B241C  00000000  ->null  
0x033B2420  00000000  ->null  
0x033B2424  00000000  ->null  
0x033B2428  00000000  (padding)
0x033B242C  7174426c  * (internal descriptor), 
0x033B2430  00000003  =3 (array[0] length)
0x033B2434  00000001  ->array[0][0]
0x033B2438  00000002  ->array[0][1]
0x033B243C  00000003  ->array[0][2]
0x033B2440  00000000  (padding)

So all the elements of int[][] are null (0 pointer) except for the first one which is initialized with the array[0] = ... statement. This element contains the address of the first array (0x033B242C in this case). So each element of array is a pointer to the internal arrays. And the internal arrays actually contain the values. See above the memory locations containing the 1,2 and 3.

John Alexiou
  • 28,472
  • 11
  • 77
  • 133