1

What will be the memory address of arr, when I am doing arr = new T[size] twice in the same scope while varying size?
Does the memory expands to new size and starting address of arr remains the same?
Or if the new memory allocation happens then the previous data get copied to new memory location?

using System;
class HelloWorld
{
    static void Main ()
    {
        byte[] arr;
        arr = new byte[6];
        arr[2] = 6;
        Console.WriteLine ("len = {0}\n{1}", arr.Length, arr[2]);
        arr = new byte[10];
        arr[2] = 10;
        Console.WriteLine ("len = {0}\n{1}", arr.Length, arr[2]);

    }
}
Orace
  • 7,822
  • 30
  • 45
Abdullah
  • 13
  • 3
  • 1
    `new byte[10]` allocates a *new* memory chunk, `arr` is a reference to this chunk; `byte[6]` is now *garbage* which can be collected by GC (garbage collector) – Dmitry Bychenko Dec 01 '21 at 09:25
  • You're writing managed (garbage collected) code and you have a compiler that may optimize this to `Console.WriteLine("len = 6\n6"); Console.WriteLine("len = 10\n10")` anyway. Asking questions like this could give interesting answers about memory management and compiler optimizations, but what have you tried? – CodeCaster Dec 01 '21 at 09:25
  • *does the memory expands to new size* - it doesn't matter/it's an implementation detail that is largely irrelevant. What is specified is that when you make a new array it will be full of 0, so there is no copying of data to any place; you'll never have an `arr= someIntArrayOf6Length` and then do `arr = new int[10]` and ever get any of the original data in your new 10-long array – Caius Jard Dec 01 '21 at 09:26
  • Anyway if you read the code as-is, you'll have two arrays in memory: one of length 6, one of length 10. And one pointer/reference variable, being `arr`, first pointing to the first, then to the second array. – CodeCaster Dec 01 '21 at 09:28
  • 1
    put `Array.Resize(ref arr, 10);` if you want `arr` be created from previous `byte[6]` array (previous data will be copied) – Dmitry Bychenko Dec 01 '21 at 09:29
  • CodeCaster : I wanted to check re-creation of the arr gives compile time error or not. – Abdullah Dec 01 '21 at 09:29
  • You're not recreating anything. `arr` _is_ not the array, it _points_ to the array. You create a _new_ array and then make `arr` point to that. – CodeCaster Dec 01 '21 at 09:30
  • 1
    *I wanted to check re-creation of the arr gives compile time error or not* - you didn't need to post a question on SO to ascertain that; you've already written the code - does it compile or not? – Caius Jard Dec 01 '21 at 09:31
  • So, what if I want to preserve the old data of arr and need it in the new arr which is expanded version of old one ? – Abdullah Dec 01 '21 at 09:37
  • Arrays do not expand; use a List (or similar expandable collection) or do what Dmitry said: copy after you make new – Caius Jard Dec 01 '21 at 09:38
  • I have the clarity now. – Abdullah Dec 01 '21 at 09:39

2 Answers2

2

new byte[6] and new byte[10] allocate new, different, memory chunks. That is, they will (probably, as mentioned in the comments) not be in the same location in memory.

arr is not the array itself. It is simply a variable that can hold a reference (the address) to a byte array. When you are reassigning it, you are simply updating its value to contain a reference to the new memory chunk, while the other one is collected by the Garbage Collector.

Michael Haddad
  • 4,085
  • 7
  • 42
  • 82
  • Can you clarify what "different" means? – Caius Jard Dec 01 '21 at 09:29
  • Even though it looks like this is the current implementation, there is no guaranty about this in the future : https://github.com/dotnet/runtime/issues/4584 – Orace Dec 01 '21 at 09:31
  • @Orace - just to clarify, the new array could potentially override the older one? – Michael Haddad Dec 01 '21 at 09:45
  • 1
    @Orace I think something like _"There is a GitHub issue where there is discussion about 'putting small objects that never leave the method onto the stack', so somewhere in the future, might that issue be implemented, both arrays may occupy the same stack frame, the first having been popped off"_ would have immediately been clearer, but thanks for clarifying. – CodeCaster Dec 01 '21 at 09:47
  • 1
    @MichaelHaddad yes, for optimization purpose. – Orace Dec 01 '21 at 09:50
  • For me, the problem is the language barrier, as I am not a native English speaker, so I am glad you clarified your comment. I edited the answer to reflect this discussion. – Michael Haddad Dec 01 '21 at 09:57
  • 1
    @CodeCaster thanks for the clearer phrasing, like Michael, I'm not a native English speaker. – Orace Dec 01 '21 at 10:02
2

According to your coding part first you have initialized the array as

arr = new byte[6];

When you again intializing the array as

 arr = new byte[10];

The array will be allocated with a size of 10 and filled with the default value (here 0). There is no data copy.
And also the byte [6] will eventually be collected by the garbage collector.

To keep the data in a resized array, you can use Array.Resize as explained here, but it will change the reference:

var arr = new byte[6];
var arr2 = arr;

Array.Resize(ref arr, 10);
// arr != arr2
Orace
  • 7,822
  • 30
  • 45
Arun_Raja1
  • 207
  • 1
  • 1
  • Even though it looks like this is the current implementation, there is no guaranty about this in the future : https://github.com/dotnet/runtime/issues/4584 – Orace Dec 01 '21 at 09:30