Указатели языка С
Указатели являются одним из основных средств языка программирования С. Они обеспечивают универсальный способ дистанционного доступа к структурам данных.
Указатели часто представляют собой источник путаницы для начинающих программистов, однако идеи, положенные в основу этих понятий, достаточно просты:
- Каждый указатель имеет тип. Этот тип показывает, на какой тип объекта он указывает. Если объект имеет тип Г, то указатель имеет тип Т. Специальный тип void представляет групповой указатель. Например, функция malloc возвращает групповой указатель, который преобразуется в типизированный указатель посредством соответствующего приведения данных.
- Каждый указатель имеет значение. Этим значением является адрес некоторого объекта заданного типа. Специальное значение NULL соответствует ситуации, когда указатель ни на что не указывает.
- Массивы и указатели тесно связаны друг с другом. На имя массива можно ссылаться, как если бы это была переменная типа указатель.
- Указатели могут указывать на функции. Это обеспечивает широкие возможности для сохранения и передачи ссылок на программный код, который может быть вызван в других частях программы.
Передача функции параметров
Другие языки программирования, такие как Паскаль, предлагают два способа передачи параметров процедуре - по значению, когда вызывающая процедура предоставляет фактические значения параметров, и по ссылке, когда вызывающая процедура предлагает указатели на фактические значения. В языке С все параметры передаются по значению, но можно имитировать результат ссылочного параметра, задавая явным способом указатель на значение и передавая этот указатель процедуре.
Переполнение буферов
Язык С не производит никаких граничных проверок ссылок на массивы, и что локальные переменные хранятся в стеке наряду с информацией о состоянии, такой как, например, значения регистров и указатели возврата. Такое сочетание может привести к серьезным программным ошибкам, когда состояние, сохраняемое в стеке, оказывается запорченным по причине записи элементов массива, значения которых выходят за допустимые границы.
Когда после этого программа делает попытку перезагрузить регистр или выполнить команду ret с подобным запорченным состоянием, это может привести к серьезным последствиям.
Чаще других причиной возникновения запорченного состояния является переполнение буфера. Довольно часто символьные массивы помещаются в стек для запоминания строки, но при этом размер строки превосходит пространство, выделенное под этот массив.
© digitrode.ru