D Динамические массивы - RAII - PullRequest
5 голосов
/ 24 мая 2011

Я признаю, что на данный момент у меня нет глубокого понимания D, мои знания основаны исключительно на том, какую документацию я прочитал, и на нескольких примерах, которые я пробовал.

В C ++ вы могли бы полагаться на идиому RAII длявызвать деструктор объектов при выходе из локальной области видимости.

Можете ли вы в D?

Я понимаю, что D - это язык для сборки мусора, и он также поддерживает RAII.Почему следующий код не очищает память, так как тогда он выходит из области видимости?

import std.stdio;

void main() {
      {
            const int len = 1000 * 1000 * 256; // ~1GiB

            int[] arr;
            arr.length = len;
            arr[] = 99;
      }

      while (true) {}
}

Существует бесконечный цикл, позволяющий держать программу открытой, чтобы сделать видимыми остаточные выделения памяти.

Сравнение аналогичной программы на C ++ показано ниже.C++ v D

Видно, что C ++ сразу же очищал память после выделения (частота обновления заставляет его выглядеть так, как будто было выделено меньше памяти), тогда как D сохранял его, даже несмотря на то, что он оставил область действия.

Следовательно, когда очищается ГХ?

Ответы [ 2 ]

5 голосов
/ 24 мая 2011

scope объявления идут в D2, поэтому я не очень уверен в семантике, но я думаю, что происходит, что scope T[] a; только распределяет структуру массива в стеке (что само собой разумеется, уже происходит, независимо от scope). По ходу дела не используйте область действия (использование scope(exit) и друзей отличается - продолжайте использовать их).

Динамические массивы всегда используют GC для выделения своей памяти - от этого никуда не деться. Если вы хотите что-то более детерминированное, то использовать std.container.Array было бы самым простым способом, так как я думаю, что вы могли бы в значительной степени уронить его туда, где ваш scope vector3b array:

Array!vector3b array

Только не удосуживайтесь установить нулевую длину - память будет свободна, как только она выйдет из области видимости (Array использует malloc / free из libc под капотом).

4 голосов
/ 24 мая 2011

Нет, вы не можете предположить , что сборщик мусора будет собирать ваш объект в любой момент времени.

Однако есть ключевое слово delete (а также ключевое слово scope), которое может детерминистически удалить объект.

scope используется как:

{
    scope auto obj = new int[5];
    //....
} //obj cleaned up here

и delete используется как в C ++ (для delete нет обозначения []).

Есть некоторые ошибки, хотя:

  • Это не всегда работает должным образом (я слышал, что это плохо работает с массивами)

  • Разработчики D (например, Андрей) намереваются удалить их в более поздних версиях, потому что он может явно испортить вещи, если используется неправильно. (Лично я ненавижу это, учитывая, что все равно все так легко испортить, но они стараются его удалить, и я не думаю, что люди могут убедить их в обратном, хотя я бы с удовольствием, если бы это был случай.)

  • Вместо него уже есть метод clear, который вы можете использовать, например arr.clear(); тем не менее, я сам не совсем уверен, что именно он делает, но вы можете посмотреть исходный код в object.d во время выполнения D, если вам интересно.


Что касается вашего удивления: я рад, что вы удивлены, но это не должно удивлять, если учесть, что они оба являются нативным кодом. : -)

...