This is a mirror of official site: http://jasper-net.blogspot.com/

Превращаем C# в C++: ручное управление памятью

| Sunday, March 13, 2011
В этой статье я хочу показать, как можно оформить ручное управление памятью в C# и сделать затем с его помощью простой однонаправленный список.

Для затравки забежим немного вперёд и покажем, как в итоге будет создаваться экземплят такого списка:
new CustomLinkedList<double, ListBasedAllocator<CustomLinkedListNode<double, int>>, int>()

Сразу условимся, что мы не будем использовать unsafe контекст. Это снижает портируемость и нивелирует всё удовольствие, что можно получить при разработке заявленного списка.

Свои указатели

К счастью (!), .NET не поддерживает указатели в том виде, в котором их поддерживает C++. Всё, что доступно при разработке управляемого кода — это
Инстансы ссылочных типов. Все они хранятся в куче и обслуживаются сборщиком мусора. Поскольку мы пишем своё управление памяти, о них можно забыть сразу.
Завёрнутые в коробку инстансы типов-значений. В принципе, они мало отличаются от инстансов ссылочных типов и нам не подходят по тем же причинам.
Управляемые указатели. Могут указывать как в кучу, так и на стек. Насколько я знаю, они могут храниться только в локальных переменных и/или передаваться в другие функции при вызове. Поэтому они нам тоже не подойдут.

Решим мы эту проблему просто: не будем её решать вообще на данном этапе, а отложим до лучших времён. Пока же договоримся везде использовать параметр типа Pointer.

Модификация структур, содержащихся в контейнерах

В этой статье я буду рассматривать аллокаторы для структур данных фиксированного размера. Опишем интерфейс такого аллокатора:

/// <summary>
/// Обобщённый интерфейс для аллокаторов объектов определённого типа.
/// </summary>
/// <typeparam name="T">Тип объектов, с которыми работает аллокатор</typeparam>
/// <typeparam name="TPointer">Тип указателя, используемый для доступа к памяти</typeparam>
public interface ICustomTypeAllocator<T, TPointer>
{
    /// <summary>
    /// Выделяет область памяти для одного объекта и возвращает указатель на эту область
    /// </summary>
    TPointer Allocate();
    /// <summary>
    /// Освобождает память, по адресу pointer.
    /// Если установлен флаг checkErrors, аллокатор по возможности производит проверку того,
    /// что данный указатель действительно указывает на ранее выделенный блок памяти,
    /// и, если это не так, генерирует исключение.
    /// </summary>
    /// <param name="pointer">Указатель на область памяти, подлежащую освобождению</param>
    /// <param name="checkErrors"></param>
    void Free(TPointer pointer, bool checkErrors = false);
    /// <summary>
    /// Позволяет осуществлять доступ к объекту по адресу pointer.
    /// </summary>
    /// <param name="pointer">Адрес области памяти, в которой находится объект.</param>
    T this[TPointer pointer] { get; set; }

Read more: Habrahabr.ru

Posted via email from Jasper-net

0 comments: