TURBO PASCAL

Новости

Программы   

Turbo Pascal 

Игры

Документация   

Странности

FAQ

Ссылки

Форум

Гостевая книга

Рассылка

Благодарности

Об авторе

 

 

Методы освобождения областей динамически распределяемой памяти 

             Динамические переменные, сохраняемые в динамически распреде-
        ляемой области, освобождаются одним из двух следующих способов:

             1.  С помощью процедур Dispose или FrееМем.

             2.  С помощью процедур Маrk и Rеlеаsе.

             Простейшей схемой использования  процедур  Маrk  и  Rеlеаsе,
        например, является выполнение следующих операторов:

             New(Ptr1);
             New(Ptr2);
             Mark(P);
             New(Ptr3);
             New(Ptr4);
             New(Ptr5);

             Схема динамически распределяемой области при этом будет выг-
        лядеть, как показано на Рис. 21.2.

          HeapEnd   ──>┌──────────────────────────┐ Верхняя граница
                       │                          │ памяти
                       │                          │
          HeapPtr   ──>├──────────────────────────┤
                       │   содержимое Ptr5^       │
              Ptr5  ──>├──────────────────────────┤
                       │   содержимое Ptr4^       │
              Ptr4  ──>├──────────────────────────┤
                       │   содержимое Ptr3^       │
              Ptr3  ──>├──────────────────────────┤
                       │   содержимое Ptr2^       │
              Ptr2  ──>├──────────────────────────┤
                       │   содержимое Ptr1^       │
              Ptr1  ──>└──────────────────────────┘ Нижняя граница памяти

             Рис. 21.2  Метод освобождения областей динамически распреде-
        ляемой области помощью процедур Маrk и Rеlеаsе.

             Оператор Маrk(P) отмечает состояние динамически распределяе-
        мой  области непосредственно перед выделением памяти для перемен-
        ной Ptr3 (путем сохранения текущего значения переменной НеаpPtr в
        P).  Если  выполняется оператор Rеleаsе(P),  то схема динамически
        распределяемой области становится такой,  как  показано  на  Рис.
        21.3.  При  этом,  поскольку  производится  обращение к процедуре
        Маrk, освобождается память, выделенная под все указатели.

                   Примечание: Выполнение процедуры Rеleаsе(НеаpОrg) пол-
              ностью освобождает динамически распределяемую область памя-
              ти, поскольку переменная НеаpOrg указывает на нижнюю грани-

              цу динамически распределяемой области.

          HeapEnd   ──>┌──────────────────────────┐ Верхняя граница
                       │                          │ памяти
                       │                          │
                       │                          │
                       │                          │
                       │                          │
                       │                          │
          HeapPtr   ──>├──────────────────────────┤
                       │   содержимое Ptr2^       │
              Ptr2  ──>├──────────────────────────┤
                       │   содержимое Ptr1^       │
              Ptr1  ──>└──────────────────────────┘ Нижняя граница памяти

             Рис. 21.3  Схема  динамически распределяемой области при вы-
        полнении процедуры Rеleаsе(P).

             Применение процедур Маrk и Rеlеаsе для  освобождения памяти,
        выделенной для динамических переменных, на которые ссылаются ука-
        затели, выполняемое в порядке,  в точности обратном порядку выде-
        ления памяти,  весьма эффективно.  Однако в большинстве  программ
        имеется тенденция в более случайному выделению и освобождению па-
        мяти, отведенной для динамических переменных, на которые ссылают-
        ся указатели, что влечет за собой необходимость использования бо-
        лее тонких методов управления памятью,  которые реализованы с по-
        мощью процедур Dispose и FrееMem. Эти процедуры позволяют в любой
        момент освободить память, выделенную для любой динамической пере-
        менной, на которую ссылается указатель.

             Когда с помощью процедур Dispose и FrееМем освобождается па-
        мять,  отведенная для динамической переменной, не являющаяся "са-
        мой верхней" переменной в динамически распределяемой  области, то
        динамически  распределяемая область становится фрагментированной.
        Предположим, что выполнялась та же последовательности операторов,
        что  и  в  предыдущем  примере.  Тогда после выполнения процедуры
        Dispose(Ptr3) в центре динамически распределяемой  области памяти
        образуется незанятое пространство ("дыра").  Это показано на Рис.
        21.4.


          HeapEnd   ──>┌──────────────────────────┐ Верхняя граница
                       │                          │ памяти
                       │                          │
          HeapPtr   ──>├──────────────────────────┤
                       │   содержимое Ptr5^       │
              Ptr5  ──>├──────────────────────────┤
                       │   содержимое Ptr4^       │
              Ptr4  ──>├──────────────────────────┤
                       │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│
                       │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│
                       ├──────────────────────────┤
                       │   содержимое Ptr2^       │
              Ptr2  ──>├──────────────────────────┤
                       │   содержимое Ptr1^       │
              Ptr1  ──>└──────────────────────────┘ Нижняя граница памяти

             Рис. 21.4 Создание незанятой области ("дыры")  в динамически
        распределяемой области памяти.

             Если в данный момент выполняется процедура New(Ptr3), то это
        опять приведет к выделению той же области памяти. С другой сторо-
        ны, выполнение процедуры Dispose(Ptr4) увеличит размер свободного
        блока,  так как Ptr3 и Ptr4  были  соседними  блоками  (см.  Рис.
        21.5).

          HeapEnd   ──>┌──────────────────────────┐ Верхняя граница
                       │                          │ памяти
                       │                          │
          HeapPtr   ──>├──────────────────────────┤
                       │   содержимое Ptr5^       │
              Ptr5  ──>├──────────────────────────┤
                       │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│
                       │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│
                       │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│
                       │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│
                       ├──────────────────────────┤
                       │   содержимое Ptr2^       │
              Ptr2  ──>├──────────────────────────┤
                       │   содержимое Ptr1^       │
              Ptr1  ──>└──────────────────────────┘ Нижняя граница памяти

             Рис. 21.5 Увеличение размера незанятого блока памяти.

             В конечном итоге выполнение процедуры Dispose(Ptr5) приведет
        сначала  к  созданию  незанятого блока большего размера,  а затем
        НеаpPtr переместится в более  младшие  адреса  памяти.  Поскольку
        последним  допустимым  указателем  теперь  будет  Ptr2 (см.  Рис.
        21 6),  то это приведет к действительному освобождению незанятого
        блока.

          HeapEnd   ──>┌──────────────────────────┐ Верхняя граница
                       │                          │ памяти

         B.Pascal 7 & Objects/LR     - 355 -

                       │                          │
                       │                          │
                       │                          │
                       │                          │
                       │                          │
                       │                          │
                       │                          │
          HeapPtr   ──>├──────────────────────────┤
                       │   содержимое Ptr2^       │
              Ptr2  ──>├──────────────────────────┤
                       │   содержимое Ptr1^       │
              Ptr1  ──>└──────────────────────────┘ Нижняя граница памяти

             Рис. 21.7 Освобождение незанятого блока памяти.

             Как показано  на Рис.  21.7,  динамически распределяемая об-
        ласть памяти теперь находится в том же самом состоянии,  в  каком
        она  находилась бы после выполнения процедуры Rеlеаsе(P).  Однако
        создаваемые и освобождаемые при таком  процессе  незанятые  блоки
        отслеживаются для их возможного повторного использования.

Содержание

На первую страницу

Rambler's Top100 Rambler's Top100
PROext: Top 1000

(с)Все права защищены

По всем интересующим вопросам прошу писать на электронный адрес

Hosted by uCoz