Кіріспе

Компьютерлік жадты бөлу түрі

Есептеу архитектураларындағы стектер – деректер соңғы кірген, бірінші шықты (LIFO) қағидасы бойынша қосылатын немесе алынып тасталатын жад аймақтары. Көптеген қазіргі заманғы компьютерлік жүйелерде әрбір жіпшеде оның стегі деп аталатын резервтелген жад аймағы болады. Функция орындалғанда, ол өзінің жергілікті күй деректерінің бір бөлігін стек жоғарғы жағына қосуы мүмкін; функция аяқталғанда, ол осы деректерді стекен алып тастауға жауапты. Міндетті түрде, қайтару операторларының дұрыс орынға оралуын қамтамасыз ету үшін, шақырушы берген қайтару мекенжайының орналасуын сақтау үшін жіпшенің стегі қолданылады. Көбінесе стек қазіргі белсенді функцияларға қатысты тұрақты ұзындығы бар айнымалыларды сақтау үшін пайдаланылады. Бағдарламашылар өзгермелі ұзындығы бар жергілікті деректерді сақтау үшін стекті нақты түрде пайдалануды таңдауы мүмкін. Егер жад аймағы жіпшенің стегінде орналасса, онда бұл жад стекте бөлінген деп есептеледі, яғни стекке негізделген жадты бөлу (SBMA). Бұл жинаққа негізделген жадты бөлу (HBMA) әдісімен салыстырылады. SBMA көбінесе функция шақыру стегімен тығыз байланысты болады.

Артықшылықтары мен кемшіліктері

Деректер соңғы қосылып, бірінші алынатындықтан, стекке негізделген жадты бөлу өте қарапайым және әдетте үйіндіге негізделген жадты бөлуден (динамикалық жадты бөлу деп те аталады) жылдам. Мысалы, C тілінде. Тағы бір ерекшелік – стектегі жад функция аяқталғанда автоматты түрде және өте тиімді түрде босатылады, егер деректер енді қажет болмаса, бұл бағдарламашы үшін ыңғайлы болуы мүмкін. (Осыған ұқсасы longjmp функциясы шақырудан бұрынғы нүктеге оралғанда да орын алады.) Егер деректерді қандайда бір түрінде сақтау қажет болса, функция аяқталмас бұрын оларды стектегі үйіндіге көшіру керек. Сондықтан, стекке негізделген бөлу уақытша деректерге немесе ағымдағы функция аяқталғаннан кейін қажет болмайтын деректерге қолайлы. Тік тізбектегі стек мөлшері кейбір кіші процессорларда бірнеше байтқа дейін кіші болуы мүмкін. Стекте қол жетімді жадтан артық жадты бөлу стек ағынына байланысты қатеге әкелуі мүмкін. Сондықтан, alloca функциясын пайдаланатын функциялардың инлайн болуына көбінесе рұқсат берілмейді: егер мұндай функция циклге инлайн болса, шақырушы күтпеген стек пайдаланудың өсуінен зардап шегеді, бұл ағынның болу ықтималдығын арттырады. Стекке негізделген бөлу шағын өнімділік мәселелерін де тудыруы мүмкін: ол өзгермелі өлшемді стек кадрларына әкеледі, сондықтан стек және кадр көрсеткіштерін басқару қажет (белгілі өлшемді стек кадрларында стек көрсеткіші артық болады, өйткені кадр көрсеткішін әр кадрдың өлшеміне көбейту жеткілікті). Бұл әдетте alloca және free функцияларын шақырудан гөрі арзан. Атап айтқанда, егер ағымдағы функцияда alloca шақырулары мен өзгермелі ұзындығы бар жергілікті деректерді қамтитын блоктар болса, alloca ағымдағы функция аяқталғанға дейін стек кадрын ұлғайтуға тырысады, ал компилятор өзгермелі ұзындығы бар жергілікті айнымалыларды стек кадрындағы бір орынға орналастыруы керек арасында қайшылық туындайды. Бұл қайшылық әдетте alloca әр шақырылғанда жеке үйінді сақтау тізбегін құру арқылы шешіледі. Тізбек әр бөлу орын алған стек тереңдігін тіркейді, ал кез келген функциядағы alloca-ға келесі шақырулар осы тізбекті ағымдағы стек тереңдігіне дейін қысқартады, содан кейін (бірақ бірден емес) осы тізбектегі кез келген сақтауды босатады. Alloca функциясын нөлдік аргументпен шақыру жадты бөлусіз босатуды іске қосу үшін де пайдаланылуы мүмкін. Alloca және жергілікті сақтау арасындағы осы қайшылықтың салдарынан alloca-ны пайдалану malloc-ты пайдаланудан тиімдірек болмауы мүмкін.

Жүйелік интерфейс

Көптеген Unix сияқты жүйелер де, Microsoft Windows та, үйіндіге негізделген malloc сияқты, стек жадын динамикалық түрде бөлуге арналған функцияны іске асырады. Компилятор әдетте оны қатарлы сілтемені басқаратын, өзгермелі ұзындығы бар массивтерді өңдеуге ұқсас, тікелей кодқа аударады. Жадты ашық түрде босатудың қажеті болмаса да, стек асып кетуі салдарынан белгісіз мінез-құлыққа ұшырау қаупі бар. Бұл функция Unix жүйелерінде 32/V (1978) нұсқасынан бастап қолданылып келген, бірақ ол Standard C немесе кез келген POSIX стандартының бөлігі емес. Microsoft Windows жүйесінде , егер бөлінетін көлем тым үлкен болса, үйіндіде жад бөліп беретін және стек асып кету қателерін хабарлайтын, қауіпсіз нұсқасы бар. Ол gnulib кітапханасын пайдалануды талап етеді, ол эквивалентті интерфейсті ұсынады, бірақ стек асып кетуі кезінде SEH ерекшелігін тудырудың орнына, аса үлкен өлшем анықталғанда функциясын шақырады. Осыған ұқсас мүмкіндікті қолмен есептеу және өлшемді тексеру арқылы эмуляциялауға болады, мысалы, glibc кітапханасында қолданылатынындай. Кейбір процессорлар отбасылары, мысалы x86, ағымдағы орындалып жатқан жіптің стегін басқаруға арналған арнайы нұсқауларға ие. Басқа процессорлар, соның ішінде RISC V, PowerPC және MIPS, тікелей стек қолдауын қамтамасыз етпейді, керісінше, конвенцияға сүйенеді және стек басқаруды операциялық жүйенің қолданбалық бинарлық интерфейсіне (ABI) жүктейді.