结构和类对象数组的内存分配

时间:2015-04-16 05:07:15

标签: c# arrays value-type reference-type

去年我正在阅读C#参考资料,在那里我看到了一个声明。请看下面的陈述。

上下文

  

使用结构而不是类的Point可以使数量有很大差异   在运行时执行的内存分配。下面的程序创建并初始化一个包含100个点的数组。   将Point实现为一个类,实例化了101个独立的对象 - 一个用于数组,另一个用于数组   对于100个元素。

class Point
{
    public int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
class Test
{
  static void Main() {
          Point[] points = new Point[100];
          for (int i = 0; i < 100; i++)
          points[i] = new Point(i, i*i);
      }
}
  

如果将Point实现为结构,如

struct Point
{
     public int x, y;
     public Point(int x, int y) {
         this.x = x;
         this.y = y;
     }
}
  

只实例化一个对象 - 数组的对象。 Point实例在内部分配   阵列。这种优化可能被滥用。使用结构而不是类也可以使应用程序运行得更慢或占用更多内存,因为按值传递结构实例会导致该结构的副本   创建

问题: 这里我的问题是如何在值类型和参考类型的情况下完成内存分配?

混乱: 为什么在参考指南中提到仅初始化1个对象。根据我对Array中每个对象的理解,将分配一个单独的内存。

修改:可能重复 这个问题与jason建议的可能重复的问题略有不同。我关注的是如何仅在值类型和参考类型的情况下分配内存,而该问题只是解释了值类型和参考类型的概述。

2 个答案:

答案 0 :(得分:19)

参考类型的数组和值类型的数组之间的差异可能更容易理解为插图:

引用类型的数组

Array of a reference type

每个Point以及数组都在堆上分配,数组存储对每个Point的引用。总共需要N + 1个分配,其中N是点数。您还需要一个额外的间接访问来访问特定Point的字段,因为您必须通过引用。

值类型

的数组

Array of a value type

每个Point都直接存储在数组中。堆上只有一个分配。访问字段不涉及间接。字段的内存地址可以直接从数组的内存地址,数组中项的索引以及值类型中字段的位置计算。

答案 1 :(得分:6)

具有引用类型的数组将包含一组引用。每个引用指向包含实际对象的内存区域:

array[0] == ref0 -> robj0
array[1] == ref1 -> robj1
...

因此,引用数组有一个内存分配(size:arraylength * sizeof(reference)),每个对象有一个单独的内存分配(sizeof(robj))。

具有值类型(如结构)的数组将仅包含对象:

array[0] == vobj0
array[1] == vobj1
...

所以jst一个内存分配大小arraylength * sizeof(vobj)