C# List方法中存储的问题
遇到一个bug,抓耳挠塞好久都没有解决,有必要记录一下。
现在我使用了一个多维list。
IList<IList<int>> list = new List<IList<int>>();
我在main函数中调用了方法函数,在方法函数中使用list.add()方法向list中添加sublist。添加代码如下:
IList<int> l = new List<int>();
for(int i=;i<;i++)
{
if (条件)
{
l.clear();
list.Add(sublist);
}
}
一共添加了3个元素
但是最终的list中,却始终只有第三个sublist,前两个sublist存在,但是为空。这就非常奇怪,既然前两个元素存在,那么就代表list.Add(sublist)语句成功运行了,但为什么值为空呢?
我第一时间就怀疑Add方法会覆盖掉之前的值,于是我又在main函数中手动添加了两个sublist,打印出来发现,后面添加的都能成功写入,只有循环内的不可以。
这段代码是在vscode里面写的,由于不能单步调试查看局部变量,耽搁了好多时间。于是我把所有代码移到了VS2017上,开始我的单步调试(VS2017大法好!)
我一步一步调试,发现第一个sublist写入是成功的,到了第二个sublist要写入的那一刻,刷!list[0]的值变成了空!
现在问题找到了,但是我不明白问题出在哪里。
在网上终于搜到了解决方法。原来是在循环中如果使用同一个sublist,那么每次add都会把之前覆盖掉。解决办法就是不要在循环外定义sublist,而是在循环内部定义。
该方法给出的解释如下:
1.对于引用类型,在循环外new了 a 对象后,这个对象的引用地址就确定了,执行到第二次list.add()时,list[0]中保存的a对象和新加的list[1] a对象是同一个对象,使用的是同一个地址,也就是说在添加list[1]是,list[0]也被修改了,因为它俩指针指向同一个地址,同样,后面添加的都会修改前面所有对象,结果就是list最后所有数据都是最后的list[end_num]。
2.string也是引用对象,有唯一的引用地址(假设分配的是address1),但当add list[1]的时候(str值改变时),.net会检查内存,发现不等于之前的字符串(list[1]不等于list[0]),.net会给原来的str重新分配内存空间address2,存储list[0],而list[1]使用原来的空间address1。这样使得每次list.add时都不会覆盖之前的元素,因为它们使用的是不同的地址空间。
————————————————
版权声明:本文为CSDN博主「IT登山家」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_35409640/article/details/71404203
但是呢,我在进一步调试中发现两个问题:
1.如果去除l.clear(),程序是正常的,list值全部正常,只有添加了l.clear(),list的前几个值才会被抹去。
2.在main函数中加这样的循环(包含l.Clear()),list可以正常写入
结合该方法,我认为覆盖的原因如下:
现在申请的所有类型在.net中都被认为是引用对象,当add的时候,.net会统一重新分配内存。但是在add之前,l都指向了l的地址,查了资料就知道,clear并不清除list内存,想必是只擦除了地址,所以才会既没有报错,也没有值。
至于在main函数中为什么不会发生这种现象,我还没有比较好的思路,可能是因为list是在main中一定,不需要引用函数,也就没有list的引用过程,可能add方法就直接写入list了。水平有限,欢迎有识之士补充。
C# List方法中存储的问题的更多相关文章
- List中存储同一个对象(内容不同)
List中存储同一个对象,前面的会被后存入的对象覆盖,解决方法:每次存入新的对象
- 数据库中存储日期的字段类型究竟应该用varchar还是datetime ?
背景: 前段时间在百度经验看到一篇文章<如何在电脑右下角显示你(爱人)的名字>,之前也听过这个小技巧,但没真正动手设置过.所以出于好奇就实践了一下. 设置完成后的效果例如以下.右下角的时间 ...
- c语言中float、double、long double在内存中存储方式
存储格式中的二机制转为浮点数: 浮点型变量在计算机内存中占用4个字节(4 Byte),即32-bit,一个浮点数由2部分组成:底数m 和 指数e: 底数部分:使用2进制数来表示此浮点数的实际值: 指 ...
- 在配置文件(.settings、.config)中存储自定义对象
原文:在配置文件(.settings..config)中存储自定义对象 引言 我前面曾写过一篇<使用配置文件(.settings..config)存储应用程序配置>,我在其中指出“sett ...
- JAVA 在程序中存储和修改信息
1.语句和表达式 计算机程序是一组告诉计算机什么的指令,每一个指令称为语句. 2.指定变量类型 变量名.变量存储的信息类型 整型int(-2.14*109~2.14*109).浮点型float(38位 ...
- 求int型正整数在内存中存储时1的个数
题目描述: 输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数. 输入描述: 输入一个整数(int类型) 输出描述: 这个数转换成2进制后,输出1的个数 输入例子: 5 输出例子: ...
- java中的各种数据类型在内存中存储的方式
原文地址:http://blog.csdn.net/aaa1117a8w5s6d/article/details/8251456 1.Java是如何管理内存的 java的内存管理就是对象的分配和释放问 ...
- 华为oj之求int型正整数在内存中存储时1的个数
题目: 求int型正整数在内存中存储时1的个数 热度指数:4427 时间限制:1秒 空间限制:32768K 题目描述 输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数. 输入描述: ...
- 数据库中存储日期的字段类型到底应该用varchar还是datetime
将数据库中存储时间的数据类型改为varchar(),这时最好让这些时间是数据库中自动生成的(一个没有格式的输入也可能会导致输出错误),因为存储类型为varchar(),所以获取到的值也就被认为是一个字 ...
随机推荐
- 代理模式-aop
https://www.jianshu.com/p/a82509c4bb0d 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期 ...
- IOS下图片不能显示问题的解决办法
最近遇到这样一个问题,在HTML5手机页面中,直接给<img>标签设置宽高,即便图片路径正常,在IOS真机下也是无法显示的,而在安卓以及浏览器的模拟真机上都是正常显示的,这是为什么呢? h ...
- DataGrid控件的列
四种列(局限性较大)https://www.cnblogs.com/lonelyxmas/p/9442604.html 更强大的模板列(如控件居中等)https://www.cnblogs.com/l ...
- java内存区域以及GC回收
参考资料: http://www.cnblogs.com/zhguang/p/3257367.html 概要: Java GC机制主要完成3件事:确定哪些内存需要回收,确定什么时候需要执行GC,如何执 ...
- 【CUDA 基础】3.2 理解线程束执行的本质(Part I)
title: [CUDA 基础]3.2 理解线程束执行的本质(Part I) categories: CUDA Freshman tags: 线程束分化 CUDA分支 toc: true date: ...
- Dell PowerEdge服务器RAID卡驱动下载
Dell PowerEdge服务器RAID卡驱动下载 DELL新阵列卡驱动下载 型号 支持系统驱动 H310/710 /710P/810 Win2008 x32 Windows 2008 x64 Wi ...
- 省市县镇村五级地址智能提取(标准地址源来自国家统计局官网)SpringBoot+Elasticsearch 5.6
项目目的 根据传入的地址,智能提取所属的省市县镇村5级地址.例如:用户输入“江苏南通嗨安李堡镇陈庄村8组88号”,我们需要提取到江苏省 南通市 海安县(即便用户输入了错字,“海”写成了“嗨”) 李 ...
- BZOJ2208连通数
还是挺简单的tarjan. 判断时可能重复,直接bitset搞定. 首先tarjan缩点,每个scc的内部肯定能互相到达,更一下,而且一个scc里的各个点的贡献肯定是一样的,topsort,更新答案就 ...
- 20165207 Exp8 Web基础
目录 20165207 Exp8 Web基础 0. 环境配置 0.1. apache 0.2. MySQL 0.3. php 0.4. php-mysql编程库 1. 前台HTML编写静态网页 2. ...
- 极光推送报错time_to_live value should be a non-negative integertime_to_live value should be a non-negative integer
文件中修改