Может ли изменение размера динамического массива интерфейсов с подсчетом ссылок с помощью SetLength () вызвать утечку памяти? - PullRequest
0 голосов
/ 03 декабря 2018

Если у меня есть следующее объявление типа интерфейса с подсчетом ссылок.

type
    ISomeInterface = interface
       ['{xxxx-xxxx-xxx-xxxx-xxx}']
       procedure doThing();
    end;

    TSomeInterfaceImpl = class(TInterfacedObject, ISomeInterface)
    public
       procedure doThing();
    end; 
...
var arrayOfSomeInterface : array of ISomeInterface; 

Будет ли следующий код причиной утечки памяти?

SetLength(arrayOfSomeInterface, 1);
arrayOfSomeInterface[0] := TSomeInterfaceImpl.create();
SetLength(arrayOfSomeInterface, 2);
arrayOfSomeInterface[1] := TSomeInterfaceImpl.create();

Из того, что я знаю, когда SetLength ()вызывается для динамического массива, он выделяет новую память для нового динамического массива, а затем копирует содержимое старого массива в новый массив.

Что произошло с подсчетом ссылок интерфейса в старом массиве.Будет ли оно правильно уменьшено?

1 Ответ

0 голосов
/ 03 декабря 2018

Нет, утечки нет.

Диспетчер памяти попытается развернуть существующий блок памяти на месте.Если это возможно, никакие ссылки не затрагиваются.Но если это невозможно, он скопирует массив в новый блок памяти.Полученные ссылки на интерфейсы будут иметь те же счетчики ссылок, что и до копирования.Увеличение размера массива не добавляет и не удаляет ссылки на существующие элементы массива, а только перемещает их из одной области памяти в другую.Это совершенно безопасно.

Оба интерфейса и динамические массивы являются управляемыми типами, компилятор и RTL будут управлять ими правильно.

...