Overwrite problem in List> in C#

Question

Saturday, October 26, 2019 7:00 AM

Hello,

I have overwrite problem in  listPrint.Add(list); 

For example: my input is : 2, 4, 6 and 8

I expected listPrint have 3 elements .

Element one: 6, 10, 14

Element two: 16, 24

Element Three: 40

But listPrint have two element. 40 and 40

How can I fix this problem?

Thanks

using System;
using System.Collections.Generic;
using System.Text;

namespace CSharp
{
    
    class Program
    {
        static List<List<int>> listPrint = new List<List<int>>();
        static void Recursively(List<int> list)
        {
            if (list.Count == 1)
            {
                Console.WriteLine(list[0]);
                return;
            }
            for (int i = 0; i < list.Count - 1; i++)
            {
                list[i] = list[i] + list[i + 1];
            }
            list.RemoveAt(list.Count - 1);
            if (list.Count != 1)
                listPrint.Add(list); // OVERWRTIE PROBLEM
                //Print(list);
            Recursively(list);
        }


        static void Print(List<int> list)
        {
         
            for (int i = 0; i < list.Count; i++)
            {
                Console.Write(list[i] + " ");
            }
            Console.WriteLine();
        }
        static void Main(string[] args)
        {
            List<int> mylist = new List<int>();
            int i = 0;
            int numberOfElements;
            Console.WriteLine("Number of Elements??");
            numberOfElements = Convert.ToInt32(Console.ReadLine());

            while(i < numberOfElements)
            {
                Console.WriteLine("Number? ");
                mylist.Add(Convert.ToInt32(Console.ReadLine()));
                i++;
            }
            Console.WriteLine();
            Recursively(mylist);

        }
        }
    }

All replies (6)

Saturday, October 26, 2019 8:42 AM âś…Answered | 1 vote

I have overwrite problem in  listPrint.Add(list); 

For example: my input is : 2, 4, 6 and 8

I expected listPrint have 3 elements .

Element one: 6, 10, 14

Element two: 16, 24

Element Three: 40

But listPrint have two element. 40 and 40

RE the contents of listPrint I think you have an issue of passing a *reference*
to the *same* list for each Add() so the results of the Lists in your List of
Lists will all point to the same List. Try creating a new List<int> for each Add.
You may have to adjust your test of the  Count accordingly. e.g. - 

static List<List<int>> listPrint = new List<List<int>>();
static void Recursively(List<int> list)
{
    if (list.Count == 1)
    {
        Console.WriteLine(list[0]);
        return;
    }
    for (int i = 0; i < list.Count - 1; i++)
    {
        list[i] = list[i] + list[i + 1];
    }
    list.RemoveAt(list.Count - 1);
    //if (list.Count != 1)
    if (list.Count != 0)
    {
        //listPrint.Add(list); // OVERWRTIE PROBLEM
        List<int> listn = new List<int>(list);
        listPrint.Add(listn);
        //Print(list);
    }
    Recursively(list);
}
  • Wayne

Saturday, October 26, 2019 7:50 AM

I wrote another program and I want the above code work the same of the below code.

The below code is fine.

using System;
using System.Collections.Generic;

namespace ConsoleApp1
{
    class Program
    {
        static void Print(List<List<int>> list)
        {
            if (list.Count == 0)
            {
                return;
            }
            for (int i = 0; i < list[list.Count-1].Count; i++)
            {
                Console.Write(list[list.Count - 1][i]);
            }
            Console.WriteLine();
            list.RemoveAt(list.Count-1);
            Print(list);

        }
        static List<List<int>> list = new List<List<int>>();
        static void Main(string[] args)
        {
            List<int> a = new List<int> { 1, 2, 3 };
            List<int> b = new List<int> { 1, 2, 3 , 4};
            List<int> c = new List<int> { 1, 2};
            List<int> d = new List<int> { 1,};
            list.Add(a);
            list.Add(b);
            list.Add(c);
            list.Add(d);
            Print(list);
        }
    }
}

Saturday, October 26, 2019 8:06 AM | 1 vote

I have overwrite problem in  listPrint.Add(list); 

For example: my input is : 2, 4, 6 and 8

I expected listPrint have 3 elements .

Element one: 6, 10, 14

Element two: 16, 24

Element Three: 40

But listPrint have two element. 40 and 40

Are you sure there is a problem? Or could it just be where and how you are
checking the list contents in the debugger?

With a breakpoint set at the last line of Main(), the debugger shows that
mylist has one element in it with a value of 40.

Altering the code slightly (as found in your original unedited post):

static void Recursively(List<int> list)
 {
     if (list.Count == 1)
     {
         Console.WriteLine(list[0]);
         return;
     }
     for (int i = 0; i < list.Count - 1; i++)
     {
         list[i] = list[i] + list[i + 1];
     }
     list.RemoveAt(list.Count - 1);
     if (list.Count != 1)
     { 
         listPrint.Add(list);
         Print(list);
     }
     Recursively(list);
 }

Sample input/output:

Number of Elements??
4
Number?
2
Number?
4
Number?
6
Number?
8

6 10 14
16 24
40

  • Wayne

Saturday, October 26, 2019 8:32 AM

Dear Friend,

Thank you for your answer,

But I still have this problem.

I insert the final code here. now the listPrint just have 0 item.

using System;
using System.Collections.Generic;
using System.Text;

namespace CSharp
{
    
    class Program
    {
        static List<List<int>> listPrint = new List<List<int>>();
        static void Recursively(List<int> list)
        {
            if (list.Count == 0)
            {
                Print(listPrint);
                return;
            }
            for (int i = 0; i < list.Count - 1; i++)
            {
                list[i] = list[i] + list[i + 1];
            }
            list.RemoveAt(list.Count - 1);
                listPrint.Add(list); 
            Recursively(list);
        }


        static void Print(List<List<int>> list)
        {
            if (list.Count == 0)
            {
                return;
            }
            for (int i = 0; i < list[list.Count - 1].Count; i++)
            {
                Console.Write(list[list.Count - 1][i]);
            }
            Console.WriteLine();
            list.RemoveAt(list.Count - 1);
            Print(list);

        }
        static void Main(string[] args)
        {
            List<int> mylist = new List<int>();
            int i = 0;
            int numberOfElements;
            Console.WriteLine("Number of Elements??");
            numberOfElements = Convert.ToInt32(Console.ReadLine());

            while(i < numberOfElements)
            {
                Console.WriteLine("Number? ");
                mylist.Add(Convert.ToInt32(Console.ReadLine()));
                i++;
            }
            Console.WriteLine();
            Recursively(mylist);

        }
        }
    }

Saturday, October 26, 2019 9:08 AM

RE the contents of listPrint I think you have an issue of passing a *reference*
to the *same* list for each Add() so the results of the Lists in your List of
Lists will all point to the same List. Try creating a new List<int> for each Add.
You may have to adjust your test of the  Count accordingly. e.g. - 

- Wayne

Thank you so much,
My problem has been solved.
But could you please more explain why this problem occurred?

*an issue of passing a *reference* to the *same* list for each Add() *


Saturday, October 26, 2019 9:32 AM | 1 vote

My problem has been solved.
But could you please more explain why this problem occurred?

List<List<int>> listPrint is a List of *references* to Lists. So when you Add
a List you are adding a *reference* to a List not a copy of the List. So every
time you change that List<int> then that change will be seen in listPrint as
the elements are all pointing to (referring to) the same List<int>.

When you keep altering list and then Add list to listPrint, what you are
Adding is a *reference* to the *same* list as was Added previously. So you
wind up with a List of *references* to (pointers to or addresses of) the
same List.

By creating a new List<int> for each Add to listPrint then Add() will add a
*reference* to a *different* List<int> each time.

  • Wayne