Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Чет про программирование / 8) Строки в памяти ПК3

.docx
Скачиваний:
24
Добавлен:
25.04.2015
Размер:
18.23 Кб
Скачать

Строки в памяти ПК

Строка – последовательность символов.

Физически переменная строкового типа представляет собой указатель на область памяти, в которой размещаются символы. Например, переменная S типа Строка на самом деле представляет собой указатель и занимает всего четыре (8) байта памяти.

  1. Паскалевские строки

Переменная строки – указатель на первый байт строки. Строка состоит из последовательно идущих подряд байт – 256 байт.

  • - фиксированная длина (неиспользованная память при коротких строках)

  • - ограниченная длина (недостаток памяти для длинных строк)

  • + нет необходимости подсчитывать длину строки

  1. Нуль-терминальные строки

Переменная строки – указатель на первый байт строки. Строка состоит из нужного количества последовательных байт и заканчивается нулевым байтом.

  • + не используется лишняя память

  • + длина строки ограничена размером ОЗУ

  • - длину строки необходимо вычислять

  • - нельзя использовать символ 0 (символ с нулевым кодом)

  1. Современные паскалевские строки (Free Pascal)

Переменная строки – указатель на первый байт строки.

При объявлении этот указатель автоматически инициализируется значением nil. Оно показывет, что строка является пустой. Функция SetLength, устанавливающая размер строки, на самом деле резервирует необходимый по размеру блок динамической памяти и записывает его адрес в строковую переменную:

SetLength(S, 100); // S получает адрес блока динамической памяти

За оператором присваивания строковых переменных на самом деле кроется копирование значения указателя, а не копирование блока памяти, в котором хранятся символы.

S2 := S1; // Копируются лишь адреса

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

Пусть в программе объявлены две строковые переменные: 

S1, S2: string; // Физически эти переменные являются указателями

И пусть в программе существует оператор, присваивающий переменной S1 значение некоторой функции:

Readln(S1); // В S1 записывается адрес считанной строки

Для хранения символов строки S1 по окончании ввода будет выделен блок динамической памяти. Блок динамической памяти, выделенный для хранения символов строки, дополнительно содержит два байта, расположенных перед первым символом. Первое поле хранит количество ссылок на данную строку, а второе - длину строки.

Если в программе встречается оператор присваивания значения одной строковой переменной другой строковой переменной,

S2 := S1; // Теперь S2 указывает на тот же блок памяти, что и S1

то, как мы уже сказали, копия строки в памяти не создается. Копируется только адрес, хранящийся в строковой переменной, и на единицу увеличивается количество ссылок на строку. При присваивании переменной S1 нового значения (например, пустой строки)

S1 := '';

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

Интересно, а что происходит при изменении символов строки, с которой связано несколько строковых переменных? Правила семантики языка требуют, чтобы две строковые переменные были логически независимы, и изменение одной из них не влияло на другую. Это достигается с помощью механизма копирования при записи (copy-on-write).

Механизм заключается в следующем: при изменении строки со счетчиком ссылок > 1 счетчик уменьшается на 1 и создается копия строки. Эта копия и изменяется. При копировании счетчик ссылок увеличивается, а если он равен 0, память освобождается.

В ЯП Паскаль

  1. String

  • Паскалевская строка {$H-}

  • Строка FP {$H+}

  1. Widestring – каждый символ 2 байта

  2. Pchar – нуль-терминальные строки

  3. UnicodeString – строка в Юникоде