OutOfBrainExcepction
OutOfBrainExcepction

Reputation: 31

Filling a list with arrays, all arrays in the list are the same (in recursive function)

I expected the following code to fill the "outputList"-list with some arrays of random integers. Turns out it doesn't. Every array in the "outputList"-list had the same numbers when I outputted the list on the console.

Any Ideas why this list is filled with the same arrays?

The random values are just to show that the output is always the same. I know there are some better ways to fill a list with random values.

Code:

    List<int[]> outputList = new();
    private static void Main()
    {
        Program program = new();
        program.StartTest();  //start non-static StartTest()-method
    }

    private void StartTest()
    {
        int[] inputArray = new int[3];   //create array {0, 0, 0}

        Test(inputArray, 10);   //call Test()-method, repeat 10 times

        for(int i = 0; i < outputList.Count; i++)  //finally print the "outputList"
        {
            string outputStr = string.Join(" ", outputList[i]);
            Console.WriteLine(outputStr);
        }
        Console.ReadLine();
    }

    private void Test(int[] array, int n)
    {
        outputList.Add(array);   //add the array to the outputList

        //fill array with random integers
        Random rand = new();
        for(int i = 0; i < array.Length; i++)
           array[i] = rand.Next(0, 1000);

        //call function again, if n > 0
        n--;
        if (n > 0)
            Test(array, n);
    }

Expected output

23 432 437

43 645 902

342 548 132

... (random values)

Actual output

252 612 761

252 612 761

252 612 761

... (always the same values)

I'm new here at stackoverflow, so please forgive any noobish mistakes I might have done.

EDIT I need the values from the array for the next iteration

Upvotes: 2

Views: 87

Answers (2)

Vadim Martynov
Vadim Martynov

Reputation: 8892

The problem is that you are passing a reference to the same array in every iteration of the Test method. When you modify the array inside the method, the changes are being reflected in all references to the same array.

You should create a new array for each iteration instead. Also it is inefficiently to fill a random index in each iteration because you can set values in some indexes many times and other indexes will never been set.

private void Test(int arraySize, int iterationsCount)
{
    var arr = new int[arraySize];
    outputList.Add(arr);  

    Random rand = new();
    for(int i = 0; i < arraySize; i++)
       arr[i] = rand.Next(0, 1000);

    n--;
    if (n > 0)
        Test(arraySize, iterationsCount);
}

A theory moment. Collection of reference types does not store the objects of these types. It stores only references to these objects. That's why it is possible that 10 values of the list contain the same reference - the address of the only array created. And accessing any index of the list will be an access to the same object by the same reference.

Upvotes: 2

Guru Stron
Guru Stron

Reputation: 142093

There are several issues with your code.

  1. The biggest one - you are modifying and adding the same instance of the array (which is a reference type) the list. One of approaches is to pass the length of array into Test method and new it up there:
 void StartTest()
{
    Test(3 , 10);   //call Test()-method, repeat 10 times
    // ...
}

 void Test(int arrLength, int iterations)
 {
    var array = new int[arrLength];
    outputList.Add(array);   //add the array to the outputList
    
    //...

    //call function again, if iterations > 0
    iterations--;
    if (iterations > 0)
        Test(arrLength, iterations);
}

Read more:

  1. The following code:
for(int i = 0; i < array.Length; i++)
   array[rand.Next(0, array.Length)] = rand.Next(0, 1000);

does not fully correspond to the desired task to generate "array of random integers". It will fill some random indexes of the array, not necessarily all of them, which "works" when the same array is used but can result in to much of zeroes when arrays are newly created for each iteration. Better to change it to:

for(int i = 0; i < array.Length; i++)
   array[i] = rand.Next(0, 1000);

P.S.

Also I would switch from recursive approach for Test to simple iterative one.

Upvotes: 1

Related Questions