Да, большинство ресурсов выделяется динамически.
Во-первых, потому что стек программе выделяется один раз сразу, а вот динамическую память все программы разделяют между собой. И пока одна программа ест гигабайт - вторая программа может жрать 10, а когда вторая завершится - первая может съесть эти 10 гигабайт. Со стеком так не получится, он должен быть непрерывен по адресам. И тогда каждой программе придется всегда выделять себе максимально возможный объем памяти, даже если он может не понадобится. Именно поэтому программы обычно не выделяют много стека.
Во-вторых, часто неизвестно заранее, сколько и каких ресурсов надо будет выделять. Плюс ресурсы могут быть использованны в куче разных функций, а значит должны жить глобально или отдельно от какой-то одной функции (например в main), но тогда все будет в куче в одном месте и это тупо неудобно.
А так, для ускорения выделения памяти есть, например, аллокаторы на стеке: Заводится локальный массив и специальный менеджер памяти вместо выделения ее в куче, выделяет куски из этого массива. Но их не используют для хранения больших объемов данных по первой причине - это очень расточительно по памяти.
Edit: да, если вам нужно больше стека, можно сделать так, чтобы программа получала больше стека. В С++ это делается параметром
линкера.