从C#中关于arraylist的引用看C#的内存管理

来源:互联网 发布:甲骨文 谷歌 java版权 编辑:程序博客网 时间:2024/05/14 02:15

从C#中关于arraylist的引用看C#的内存管理

都说C#很多地方是学java的,而且学的很像。。。。

还是有些地方露了小尾巴的。。。。

我们还是用代码说话吧。。。。。。。。。。。。。。。。

 

             System.Collections.ArrayList temp = new System.Collections.ArrayList();
             System.Collections.ArrayList ea_row = new System.Collections.ArrayList();
            double temp1 = 0;
            double temp2 = 0;
            for (int k = 0; k < entry.yinzi.Count; k++)
            {       
               

                temp.Clear();
                for (int i = 0; i < int.Parse(entry.chushishuju.Count.ToString()) / int.Parse(entry.yinzi[k].ToString()); i++)
                {
                   
                   
                    ea_row = (System.Collections.ArrayList)ea[k];
                   
                    for (int j = 0; j < int.Parse(entry.yinzi[k].ToString()); j++)
                    {
                        //double.Parse(entry.chushishuju[i * int.Parse(entry.yinzi[i].ToString()) + j].ToString()) -
                        temp2 = double.Parse(entry.chushishuju[i * int.Parse(entry.yinzi[k].ToString()) + j].ToString()) -        double.Parse(ea_row[i].ToString());
                        temp1 += System.Math.Pow(temp2, 2);

                       
                    }
                        temp1 = System.Math.Sqrt(temp1 / (double.Parse(yinzi[k].ToString()) - 1));
                        temp.Add(temp1);
                       
                }
               Sr1.Add(temp);
            }

这段代码的意图是构造一个二维动态数组,Sr1的每个元素都是由一个数组组成,并且每次计算的结果都保存在Sr1中,但是实际运行我们发现,在Sr1中,元素的个数与我们预期的相同,但是数值都是相同的,即为最后一次计算的数值。

这是为什么呢?广星师兄曾经说过:要相信计算机是不会闹鬼滴~~~

闹鬼的只能是我们自己。。。。。。debug后发现,原来C#的托管模式虽然没有指针,但是在引用object类型对象的时候,并没有拷贝,而是简单的存储了对象的地址,所以用上述方法在Sr1中存储的为temp的地址。所以回调的时候发现Sr1全部元素都是一样的。

解决办法:对于每个循环,都重新申请内存空间,申请不同的地址,

double temp1 = 0;
            double temp2 = 0;
            for (int k = 0; k < entry.yinzi.Count; k++)
            {      
                System.Collections.ArrayList temp = new System.Collections.ArrayList();
                System.Collections.ArrayList ea_row = new System.Collections.ArrayList();
                temp.Clear();
                for (int i = 0; i < int.Parse(entry.chushishuju.Count.ToString()) / int.Parse(entry.yinzi[k].ToString()); i++)
                {
                   
                   
                    ea_row = (System.Collections.ArrayList)ea[k];
                   
                    for (int j = 0; j < int.Parse(entry.yinzi[k].ToString()); j++)
                    {
                        //double.Parse(entry.chushishuju[i * int.Parse(entry.yinzi[i].ToString()) + j].ToString()) -
                        temp2 = double.Parse(entry.chushishuju[i * int.Parse(entry.yinzi[k].ToString()) + j].ToString()) - double.Parse(ea_row[i].ToString());
                        temp1 += System.Math.Pow(temp2, 2);

                       
                    }
                        temp1 = System.Math.Sqrt(temp1 / (double.Parse(yinzi[k].ToString()) - 1));
                        temp.Add(temp1);
                       
                }
               Sr1.Add(temp);
            }

这样在运行过程中,每次执行System.Collections.ArrayList temp = new System.Collections.ArrayList();
                System.Collections.ArrayList ea_row = new System.Collections.ArrayList();
都会重新分配内存空间,将指针值向新的内存空间。原来的地址被存储到Sr1中。并没有被回收,还是可以通过Sr[i] 引用的,达到了目的。

由此看出C#的内存管理并没有java那么严谨,还是有可能引发内存泄漏和野指针问题,只是不使用指针你不知道罢了