日期:2014-05-18  浏览次数:20957 次

内存 关于数据结构内数组
写了一段测试代码,见下面。关于内存,out 关键字,等有不少疑问。
期待高手解答。
谢谢先。 

  PassData pass1;
  PassData pass2;
private void TestStructOut()
{  
  int id = 2;
  TestStruct.OutStruct(id, out pass1);
  id = 4;
  TestStruct.OutStruct(id, out pass2); 
 //测试发现
// 1 结构是值传递;
// 2 pass2.feed与pass1.feed没有任何关联。
// 疑问: 结构体的成员feed是在静态函数OutStruct内申明的,out传出来,它的生存期有多长?或者说,现在pass1与pass2的数据成员feed在整过生存期内都可靠吗?
谢谢。
}

  struct PassData
  {
  int ID;
  int pass;
  int[] feed;
  public PassData(int id)
  {
  ID = id;
  pass = id + 10;
  feed = new int[pass];
  for (int i = 0; i < pass; i++)
  {
  feed[i] = pass * i;
  }

  }

  }


  class TestStruct
  {
  static public void OutStruct(int id, out PassData pass)
  {
  pass = new PassData(id);
  }
  }

------解决方案--------------------
1.结构的赋值会将对应字段一一拷贝,是一次浅拷贝
2.数组是类,在结构内保存的是对数组实例的引用
3.只要还保留对对象的强引用,对象就不会被垃圾回收。当代码再也不能访问一个对象时(从应用程序“根”向下遍历),它会在下次垃圾回收被销毁。
------解决方案--------------------
out和结构的生存周期没有什么关系,其实out不是把结构传出来,而是把pass1/pass2的地址传给OutStruct方法,OutStruct引用它们的地址并改变这两个结构实例的内容,

pass1/pass2的生存周期是定义它们的地方决定的,看样子应该是类变量,和类实例生存周期相同,没用的时候会被垃圾回收机制回收,
------解决方案--------------------
feed = new int[pass];这句话就导致了pass1/pass2的feed成员没有任何关系,至于feed的生存周期,要看是否还有引用,其实pass1/pass2只要还存在,也就是pass1/pass2所在的类实例没有被回收,feed就会被引用,就不会被回收,

pass1/pass2的生存周期和他们所在的类实例相同,和OutStruct方法无关,OutStruct方法只是接收了pass1/pass2的地址而已,不会影响它们的生存周期,也不会决定pass1/pass2在堆还是在栈了,这个情况应该是在堆里,至于feed作为引用类型,它肯定是在堆里分配,只要还有引用,feed就不会被回收,