:: PASCAL :: ТЕОРИЯ  
 

 

Лекция 10

  

 

Распределение памяти

 

1. Постановка задачи.  

  Проблема: при решении задач, в которых предполагается обработка массивов, встает вопрос об объявлении типов массива, определении переменных и выделении памяти для хранения элементов массивов. Например, объявлен тип:  

 

  const number = 15000;  
  type massiv = array[0..number] of longint;  
  var chisla : massiv;  

 

  Какие бы конкретные обработки не включались в данной задаче, пройдет все. Однако, проблемы начнутся в том случае, если потребуется обработка не 15000, а 20000 тысяч элементов типа longint. При попытке запуска данной редакции той же программы возникнет сообщение  

 

  «Error 22: Structure too large.»  

 

  Это значит: «Ошибка 22: Структура чересчур объемиста»  
 

Теперь в меню Help можно выбрать пункт Error messages, а затем выбрать пояснение о сути ошибки. Оно гласит, что максимальный размер для структурированных типов составляет 65520 байт. Что это значит? Для хранения одного элемента типа longint требуется 4 байта памяти, а для массива из 15000 элементов – 60000 байт. При этом раскладе программа работает правильно. Если же потребуется хранение 20000 элементов, то это значит и 80000 байт памяти. Таким образом, превышается максимальный объем памяти. Выход из данной ситуации, в том числе и для работы с массивами, большими 20000 элементов, в языке Паскаль возможен и представляется в виде использования динамической памяти и указателей.  

 

До сих пор мы имели дело с так называемыми статическими данными и статическими переменными. Такие переменные объявляются в начале программы (в разделе описаний) и существуют до завершения ее работы. Соответственно, память для содержания этих переменных выделяется при запуске программы и остается занятой все время, пока программа работает.  

 

Очевидно, что это не самый рациональный способ использования памяти компьютера. Например, некоторая переменная может использоваться только однажды в единственном операторе обширной программы, однако память, выделенная под эту переменную, остается занята все время, пока работает программа. А нельзя ли сделать так, чтобы память для такой переменной выделялась в момент, когда переменная начинает использоваться, и освобождалась сразу же по завершении ее использования? И чтобы эту память тут же можно было выделить для иных данных? Вот такого рода проблемы и могут быть решены с помощью динамической памяти.  

 

Динамическая память, известная также как «куча», рассматривается в Turbo Pascal как массив байтов, который имеет объем порядка 300000 байт. Это позволяет обрабатывать массивы гораздо большего объема.  

 

Рассмотрим, как происходит распределение оперативной памяти в системе программирования Турбо Паскаль 7.0. Если вы решаете простые задачи, то и программы у вас, как правило, получаются небольшие. А для небольших программ, использующих сравнительно немного данных, проблем с распределением памяти обычно не возникает. Но как только задачи, стоящие перед вами, усложняются, память сразу же дает о себе знать: то ее не будет хватать для размещения кодов самих программ, то недостаточной оказывается область, выделенная под глобальные или локальные данные. Для того чтобы знать, как поступать в таких и многих других случаях, необходимо иметь представление о принципах распределения памяти, используемых в системе программирования Турбо Паскаль 7.0.  

 

 

2. Карта памяти.  

  Вся оперативная память, выделяемая для работы программы, написанной на Турбо Паскале, делится на сегменты.  
  Сегмент – это непрерывный участок памяти, размер которой не превышает 65536 байт.  
  ü   один сегмент всегда необходим для размещения кода главной программы;  
  ü   если программа имеет модульную структуру, то дополнительно по одному сегменту выделяется для каждого модуля;  
  ü   память обязательно выделяется под системный модуль SYSTEM, -  
  все эти сегменты носят название сегментов кода.  
  Еще один сегмент необходим для размещения глобальных переменных и типизированных констант (к ним относятся статические переменные и константы, объявленные в главной программе и в секциях связей модулей).  
  Последним является сегмент стека, служащий в основном для размещения локальных данных подпрограмм и внутренних данных модулей.  
  Еще раз отметим, что длина любою из этих сегментов не может превосходить 64К. Размеры всех сегментов, кроме сегмента стека определяются в процессе компиляции и во время работы программы не меняются. Размер сегмента стека может устанавливаться программистом с помощью директивы компилятора, имеющей вид  
  {$М <размер стека>, <мин. объем дин. памяти>, <макс, объем дин. пам.>}  
  Размер сегмента стека не может превышать 64К; по умолчанию, т. е. в случае отсутствия соответствующей директивы, размер стека устанавливается равным 16К.  
  За сегментом стека размещается оверлейный буфер, размер которого может устанавливаться программистом.  
  Оставшаяся свободной область частично или полностью может быть занята динамической памятью. В ней размещаются динамические переменные.  
  Сегменты программы располагаются в памяти в определенном порядке:  
  сначала – сегмент главной программы,  
  затем – кодовые сегменты модулей, сегмент кода модуля SYSTEM,  
  следом – сегмент данных  
  и, наконец, сегмент стека.  
  Все версии системы программирования Турбо Паскаль кроме последней 7.0 могли адресовать только 640К байт памяти. То есть, все сегменты, оверлейный буфер и динамические переменные должны были помещаться в области памяти с адресами от 0 до 640К. В седьмой версии это ограничение снято и карта памяти выглядит следующим образом:  

 

  Адреса в персональных компьютерах состоят из двух шестнадцатеричных слов – адреса сегмента и смещения. Сегмент может начинаться только с физического адреса кратного 16. Смещение показывает положение участка памяти относительно начала сегмента. Задав нужное смещение, можно обратиться к любому байту данного сегмента.  
  Для работы с динамической памятью в Турбо Паскале, как и во многих других языках, используются указатели. Указатель занимает четыре байта и содержит в двух старших байтах значение адреса сегмента, а в двух младших – смещение. С помощью указателей можно размещать в динамической памяти переменные любых типов. Указатель в этом случае будет ссылаться на первый байт области памяти, выделенной переменной.  

   
::  

::


Rambler's Top100 Крапивна
 

(с)2005-2006 Web studio SEDUVAN

Hosted by uCoz