Страница 34 из 39
Проблема указателей Наиболее часто ошибки в Турбо Паскале связаны с неправильным употреблением указателей. Проблемы указателей делятся на две ос- новные категории: недоразумения с действиями над указателями и случайное применение недопустимых указателей. Для разрешения проблем первого типа вы должны разобраться с указателями в языке Паскаль; для разрешения проблем второго типа вы должны всегда проверять допустимость указателей перед их применением. Следующая программа иллюстрирует типичную ошибку с указате- лем, которую допустил программист: program WRONL; {данная программа имеет ошибку}
type pntr = ^obiect;
obiect = record x: char; y: integer; name:string[80]; end;
var p: pntr;
begin p^.name := 'tom'; p^.x := 'g'; p^.y := 100; end.
Данная программа может аварийно завершиться, так как указа- тель р не принимает значение, используя New. Указатель р содержит неизвестное произвольное число, которое может указывать куда угодно в памяти компьютера. Это совсем не то, что вы хотели. Для исправления этой программы вы должны добавить строку
New(p);
до первого использования р. "Дикий" указатель крайне трудно выследить. Если вы осущест- вляете присваивание указателю значение переменной, которая не со- держит недопустимый адрес, ваша программа некоторое время может работать правильно, а крах наступит после. Статистически, чем меньше ваша программа, тем больше вероятность того, что она будет работать правильно даже со сбившимся указателем, так как исполь- зуется меньше памяти. По мере роста вашей програмы ошибка стано- вится более вероятной. Во-вторых, наиболее коварные проблемы могут возникнуть, ког- да используются указатели: вы можете выйти за пределы памяти в течение вызова New во время выполнения. Это вызывает ошибку во время выполнения и оно прекращается. К счастью в Турбо Паскале есть специальная встроенная функция MemAvail так, что вы можете избежать этих проблем. MemAvail возвращает число свободных байт слева от неупорядоченного массива. В версиях, предшествующих 4.0, MemAvail возвращает число параграфов свободной памяти. Следова- тельно, чтобы сделать программу полностью правильной, проверяйте наличие свободной памяти перед ее выполнением. Чтобы сделать это, вы должны знать число байт, необходимое для каждого типа данных, которые вы размещаете. Однако, это число может изменяться в зави- симости от процессора и операционной системы, поэтому используйте функцию SizeOf, которая возвращает число байт, требующихся для переменной. Измененная программа выглядит следующим образом:
program RIOHL; {это верная программа}
type pntr = ^object;
object = record x: char; y: integer; name:string[80]; end;
var p: pntr;
begin if MaxAvail>=SizeOf(object) then begin {свободная память} New(p); p^.name := 'tom'; p^.x := 'g'; p^y := 100;
end; end.
Одним из указаний на проблему с указателем является то, что ошибка ведет к неустойчивости в поведении. Ваша программа может работать один раз правильно, а другой раз неправильно. Иногда другие переменные будут содержать мусор без видимых причин. Если такое происходит, проверьте ваши указатели. Хотя указатели являются вещью хлопотной, они также являются одним из самых мощных и полезных аспектов языка Паскаль. Приложи- те усилия заранее, чтобы научиться правильно ими пользоваться.
|