Можем ли мы выделить память стека во время выполнения?

Когда функция рекурсивно вызывает себя и сохраняет предыдущее состояние в стеке, можем ли мы вызвать память, выделенную во время выполнения? Эта память стека вызовов не выделяется во время компиляции, поэтому можно ли с уверенностью заключить, что мы можем выделить память стека во время выполнения?

Меня немного смущают материалы в Интернете, в которых говорится, что распределение памяти во время выполнения — это другое название динамического распределения памяти, что, на мой взгляд, является чрезмерным упрощением.

Это функция платформы, поэтому отметьте свой вопрос той операционной системой, которую вы используете. В Linux вы можете использовать pthread_attr_setstack, чтобы установить размер стека потока перед его созданием во время выполнения. ulimit и во время выполнения setrlimit() используется для установки размера стека (вплоть до жесткого предела) перед созданием процесса. Я не думаю, что возможно изменить размер существующего процесса/потока.

Allan Wind 30.08.2024 09:03

Размер кадра стека обычно задается во время компиляции с помощью параметров функций и локальных переменных. Некоторые компиляторы предоставляют функцию alloca, которая позволяет динамически распределять память в стеке. Распределение кадров стека выполняется во время выполнения вашей ОС.

Raildex 30.08.2024 09:12

Как объясняет Аллан, это зависит от ОС. При вызове функции память для кадра стека функции резервируется. Например, Linux по умолчанию резервирует стек 4 МБ, а Windows — стек 1 МБ. Ячейка памяти, где начинается резервирование, сохраняется, поэтому при выполнении возврата функции можно вернуться туда. Вашим локальным переменным предоставляется хранилище из этого блока. Какая часть известности стека используется, зависит от количества используемых локальных переменных. В рекурсивном случае следующий кадр стека функций начнется после памяти для локальных переменных для текущего (и красной зоны в x86_64).

David C. Rankin 30.08.2024 09:15

Я бы сказал, что вызов функции будет использовать ранее выделенное пространство стека. На странице руководства для alloca() написано «выделяет размерные байты пространства в кадре стека», но это находится в (предварительно выделенном) кадре стека.

Allan Wind 30.08.2024 09:16

См. Компоновка стекового фрейма на x86-64

David C. Rankin 30.08.2024 09:25
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
69
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Память стека всегда выделяется во время выполнения, но в языке C конкретно не упоминается, как и где выполняется выделение. И, следовательно, C не позволяет нам напрямую манипулировать стеком, и это хорошо.

Некоторые нестандартные функции, такие как alloca, могут позволять выделение стека. Также весьма вероятно, что массивы переменной длины (VLA) размещаются в стеке. В любом случае библиотека или компилятор обрабатывают выделение/освобождение, как и в случае с любой стековой памятью.

«Выделение памяти во время выполнения» и даже «динамическое выделение памяти» не являются формальными терминами, поэтому они могут означать что угодно. Хотя динамическое распределение памяти является общепринятым де-факто стандартным названием для выделенного хранилища/свободного хранилища/распределения кучи... или как-то еще это можно назвать. Формальный термин, используемый в стандарте C, — выделенная память.

Другие вопросы по теме