Выделение памяти для массива Struct и Class Object

В прошлый день я читал справочник по 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 объект. Насколько я понимаю, для каждого объекта в массиве будет выделена отдельная память.

Изменить: возможный дубликат. Этот вопрос немного отличается от возможного дублирования вопроса, предложенного Джейсоном. Меня беспокоит то, как выделяется память только в случае типа значения и ссылочного типа, в то время как этот вопрос просто объясняет обзор типа значения и ссылочного типа.


person Zeb-ur-Rehman    schedule 16.04.2015    source источник
comment
Этот вопрос фактически дублирует этот вопрос. Хотя вы говорите о массиве ссылочных типов или типов значений, а не об отдельных переменных, может возникнуть тот же вопрос.   -  person kjbartel    schedule 16.04.2015
comment
Хорошо, спасибо Джейсону за проявленный интерес. Я думаю, что мой вопрос немного отличается от того, что вы предлагаете, потому что в моем случае я знаю, в чем разница между структурами и классом, мне интересно узнать, как распределение памяти выполняется в C # в случае массива структур и массива объектов класса . Еще раз спасибо за вашу помощь.   -  person Zeb-ur-Rehman    schedule 16.04.2015
comment
Тот факт, что вы задаете вопрос, показывает мне, что на самом деле вы не понимаете разницы между типами значений и ссылочными типами в C #, потому что разница заключается в распределении памяти. Как показывает DrKoch, это либо массив ссылок на объекты в куче, либо массив структур (или другой тип значения) как один непрерывный блок памяти. Таким образом, будь то массив или просто переменная, это одно и то же. Следовательно, это дубликат.   -  person kjbartel    schedule 16.04.2015


Ответы (2)


Возможно, разницу между массивом ссылочного типа и массивом типа значения легче понять с помощью иллюстрации:

Массив ссылочного типа

Массив ссылочного типа

Каждый Point, а также массив размещается в куче, и в массиве хранятся ссылки на каждый Point. Всего вам нужно N + 1 распределения, где N - количество баллов. Вам также понадобится дополнительная косвенная ссылка для доступа к полю конкретного Point, потому что вам нужно пройти через ссылку.

Массив типа значения

Массив типа значения

Каждый Point хранится непосредственно в массиве. В куче есть только одно выделение. Доступ к полю не предполагает косвенного обращения. Адрес памяти поля может быть вычислен непосредственно из адреса памяти массива, индекса элемента в массиве и местоположения поля внутри типа значения.

person Martin Liversage    schedule 16.04.2015

Массив ссылочных типов будет состоять из массива ссылок. Каждая ссылка указывает на область памяти, которая содержит фактический объект:

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

Таким образом, существует одно выделение памяти для массива ссылок (size: arrayylength * sizeof (reference)) и отдельное выделение памяти для каждого объекта (sizeof (robj)).

Массив с типами значений (например, структурами) будет содержать только объекты:

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

так что есть jst одно выделение памяти с размером arrayylength * sizeof (vobj)

person DrKoch    schedule 16.04.2015