05.09.2016 Views

Стефан Р. - С++ Для чайников

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Проблемы области видимости<br />

Приведенный ниже фрагмент программы будет скомпилирован, но не будет корректно<br />

работать.<br />

double 1<br />

child(void)<br />

{<br />

double dLocalVariable;<br />

return fidLocalVariable;<br />

)<br />

void parent(void)<br />

<<br />

double* pdLocal;<br />

pdLocal = child ();<br />

*pdLocal = 1.0;<br />

)<br />

Проблема в том, что переменная dLocalVariable объявлена внутри функции<br />

child(). Следовательно, в момент возврата адреса dLocalVariable из child () самой<br />

переменной уже не существует и адрес ссылается на память, которая вполне может<br />

быть занята для каких-то других целей.<br />

5<br />

* ' Ошибки такого типа встречаются довольно часто, а способы их появления<br />

весьма разнообразны. К сожалению, такой тип ошибки пропускается<br />

компилятором и зачастую не вызывает аварийной остановки программы.<br />

Программа может отлично работать большую часть времени,<br />

пока память, которая в прошлом выделялась под dLocalVariable, не<br />

будет выделена другой переменной. Труднее всего найти ошибки, проявляющиеся<br />

спонтанно.<br />

Использование блока памяти<br />

Ошибки области видимости возникают потому, что C++ освобождает выделенную<br />

для локальных переменных память автоматически. <strong>Для</strong> решения этой проблемы необходим<br />

блок памяти, контролируемый непосредственно программистом. В этом блоке<br />

можно выделять память под переменные и удалять их независимо от того, что по этому<br />

поводу "думает" C++. Такой блок памяти называется кучей (heap).<br />

Память в куче можно выделить, используя оператор new; он пишется вместе с типом<br />

объекта, под который нужно выделить память. Приведенный ниже пример выделяет<br />

из кучи память для переменной типа double.<br />

double* child{void)<br />

i<br />

double* pdLocalVariable = new double;<br />

return pdLocalVariable;<br />

I<br />

Теперь, несмотря на то что переменная pdLocalVariable имеет область видимости<br />

в пределах функции child(), память, на которую указывает эта переменная, не<br />

будет освобождена после выполнения функции. Выделение и освобождение памяти<br />

в куче осуществляется только явно. Освобождение памяти в куче выполняется с помощью<br />

команды delete.<br />

void<br />

{<br />

parent(void)<br />

// функция child() возвращает<br />

// адрес переменной в куче<br />

double* pdMyDouble = child();<br />

96 Часть II. Становимся программистами

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!