C # list method stored in the problem

I encountered a bug that has not been resolved by scratching the earplug for a long time. It is necessary to record it.

Now I use a multi-dimensional list.

IListint>> list = new Listint>>();

I call it in the main function In the method function, use the list.add() method in the method function to add a sublist to the list. Add the code as follows:

IList<int> l = new List<int>();

for(int i=0;i<10;i++)
{
if (condition)
{
l.clear();
list.Add(sublist);
}
}

A total of 3 elements are added

But in the final list, there is always only the first Three sublists, the first two sublists exist, but empty. This is very strange. Since the first two elements exist, it means that the list.Add(sublist) statement has run successfully, but why is the value empty?

I suspected that the Add method would overwrite the previous value for the first time, so I manually added two sublists to the main function. After printing it out, I found that the ones added later can be written successfully, only Not within the loop.

This code was written in vscode. It took a lot of time to debug and view local variables in a single step. So I moved all the code to VS2017 and started my single-step debugging (VS2017 is great!)

I debugged step by step and found that the first sublist was successfully written, and the second sublist was reached. The moment you want to write, brush! The value of list[0] becomes empty!

Now the problem is found, but I don’t understand where the problem is.

I finally found a solution on the Internet. It turns out that if the same sublist is used in the loop, each add will overwrite the previous one. The solution is not to define the sublist outside the loop, but to define it inside the loop.

The explanation given by this method is as follows:

1. For the reference type, after the a object is new outside the loop, the reference address of this object is determined and executed To the second list.add(), the a object saved in list[0] and the newly added list[1] a object are the same object, using the same address, that is to say, adding list[1 ]Yes, list[0] has also been modified, because the two pointers point to the same address. Similarly, all the objects added later will be modified. The result is that all the data at the end of the list is the last list[end_num].

2.string is also a reference object, with a unique reference address (assuming address1 is allocated), but when add list[1] (when the value of str changes), .net will check the memory and find Not equal to the previous string (list[1] is not equal to list[0]), .net will re-allocate memory space address2 to the original str, store list[0], and list[1] uses the original space address1. In this way, every time list.add will not overwrite the previous elements, because they use different address spaces.
————————————————
Copyright statement: This article is the original article of the CSDN blogger “IT Mountaineer”, following the CC 4.0 BY-SA copyright agreement, please reprint Attach a link to the original source and this statement.
Original link: https://blog.csdn.net/qq_35409640/article/details/71404203

However, I found two problems in further debugging:

1. If l.clear() is removed, the program is normal, and the list values ​​are all normal. Only if l.clear() is added, the first few values ​​of the list will be erased.

2. Add such a loop (including l.Clear()) to the main function, and the list can be written normally

Combined with this method, I think the reason for the coverage is as follows:< /p>

All types currently applied for are regarded as reference objects in .net. When add, .net will uniformly reallocate memory. But before add, l points to the address of l. After checking the data, we know that clear does not clear the list memory, presumably only the address is erased, so there is neither an error nor a value.

As for why this phenomenon does not happen in the main function, I still don’t have a better idea. It may be because the list is definitely in the main, and there is no need to reference the function, so there is no list reference process. , The add method may be directly written into the list. The level is limited, and people of insight are welcome to add.

IListint>> list = new Listint>>();

IList<int> l = new List<int >();

for(int i=0;i<10;i++)
{
if (condition)
{
l.clear();
list.Add(sublist);
}
}

Leave a Comment

Your email address will not be published.