Std::cout << b << std::endl; // выведет 3

}

 

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

 

Ниже представлено содержимое стека в 3 момента времени, соответствующие состояниям до вызова функции f, внутри его и после возврата в функцию main:

 

voidf ( intx )

{

inty = x + 4; // Точка 2

// ...

}

 

intmain ()

{

int a = 5; // Точка 1

f( 3 );

// Точка 3

}

 

Служебная информация о вызове: адрес возврата, сохраненные регистры ...
 
Переменная а в функции main
1)
 
2)
Вершина
?
Вершина
Переменная а в функции main
Аргумент функции
Переменная y в функции f
 
3)
?
Вершина
Переменная а в функции main
Уже свободная часть стека, будет затерта в любой момент

 

В отличие от сегмента кода и сегмента данных, точный необходимый размер для стека вычислить во время компиляции не представляется возможным, т.к. функции могут вызывать друг друга с очень большим и непредсказуемым уровнем вложенности. Соответственно, выделяется некоторый конечный достаточно большой для общего назначения размер. Этот размер зависит от используемого компилятора и может быть настроен в случае необходимости. Программы в среде Visual Studio по умолчанию получают стек размером 1 мегабайт. Достичь данного предела не так уж сложно, достаточно объявить внутри функции слишком большой по размеру массив:

 

intmain ()

{

charbuf[ 2000000 ];

buf[ 0 ] = 'a';

}

 

Запуск такой программы приведет к ошибке переполнения стека:

 

 

Из этого вытекает, что стек не предназначен для хранения больших объемов данных, а должен использоваться лишь для промежуточных переменных и аргументов функций.

 

Переполнение стека также может случиться из-за слишком глубокого уровня вложенности вызовов функций. Это легко продемонстрировать на приведенной ниже некорректной рекурсивной функции. Хотя функция и не содержит ни одного локальной переменной и ни одного аргумента, объем сохраняемой служебной информации через некоторое время превысит ограничение на размер стека:

 

intf ()

{








Дата добавления: 2016-01-29; просмотров: 686;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.005 сек.