Предел распределения стека для программ на 32-битной машине Linux

В С++ насколько сегмент стека будет расти до того, как компилятор откажется и скажет, что он не может выделить больше памяти для стека.

Использование gcc на 32-битной машине linux (fedora).

Ответ 1

В UNIX, если вы используете bash run

$ ulimit -a

в нем будут перечислены различные ограничения, включая размер стека. Шахта 8192kb. Вы можете использовать ulimit для изменения пределов.

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

$ man 3 ulimit

В Windows смотрите StackReserveSize и StackCommitSize

На практике адреса стека начинаются с высоких адресов (на 32-битной платформе, близкой к пределу 3 ГБ) и уменьшаются, когда распределение памяти начинается с низких адресов. Это позволяет стеку и памяти расти до тех пор, пока вся память не будет исчерпана.

Ответ 2

В моем 32-битном Linux файле его 8192K байтов. Поэтому на вашей машине должно быть одинаково.

$ uname -a
Linux TomsterInc 2.6.28-14-generic #46-Ubuntu SMP Wed Jul 8 07:21:34 UTC 2009 i686 GNU/Linux
$ ulimit -s
8192

Ответ 3

Windows (и, я думаю, Linux) работают на основе предположения о большой модели модели, т.е. есть один стек (для потока), пространство которого предварительно распределено до начала потока. Я подозреваю, что ОС просто назначает пространство виртуальной памяти предварительно распределенного размера этой области стека и добавляет страницы реальной памяти под конец, так как конец стека продвигается за пределы границы страницы до тех пор, пока не будет достигнут верхний предел ( "ulimit" ).

Поскольку ОС часто размещают стеки вдали от другой структуры, когда достигается ulimit, возможно, что ОС может расширить стек, если при переполнении ничего больше не отображается рядом с стеком. В общем случае, если вы создаете сложный программный комплекс, достаточный для, вы, скорее всего, распределяете память динамически, и нет никакой гарантии, что область рядом с стекем не будет выделена. Если такая память выделена, конечно, ОС не может расширить стек, где она есть.

Это означает, что приложение не может рассчитывать на то, что стек автоматически расширяется ОС. По сути, стек не может расти.

Теоретически, приложение, исчерпывающее его стек, могло бы начать новый поток с большим стекем, скопировать существующий стек и продолжить, но по практическим соображениям я сомневаюсь, что это можно сделать, если только по какой-либо причине, кроме указателей на стек локальных переменных потребуется настроить, а компиляторы C/С++ не позволяют найти такие указатели и настроить их. Следствие: ulimit должен быть объявлен до запуска программы, и один раз превышен, программа умирает.

Если требуется стек, который может произвольно расширяться, лучше переключиться на язык, который использует записи активации с помощью кучи. Тогда вы просто не закончите, пока ваше адресное пространство не будет исчерпано. 32 или 64-битные виртуальные пространства гарантируют, что вы сможете много рекурсии с этой техникой.

У нас есть параллельный язык программирования PARLANSE, который делает выделение кучи, чтобы позволить тысячам параллельных вычислительных зерен (на практике) рекурсивно рекурсивно проходить этот путь.