Подтвердить что ты не робот

Размер стека и памяти кучи

Возможный дубликат:
Что и где находится стек и куча?

Что касается основных концепций макета памяти в программе c, я понимаю следующее:

  • Язык использует две первичные структуры данных стек и куча.
  • Создан стек для хранения локальных переменных и хранения данных подпрограмм
  • Куча создана для хранения динамически распределенных переменных программы
  • Куча имеет переменную длину в природе. (Не очень уверен в стеке)
  • Обычно компилятор/язык несет ответственность за запрос ОС на создание этих структур данных до выполнения.

Вопросы

  • Каков первоначальный размер, с которым создается стек/куча? и кто его решает?
  • В какой физической памяти они созданы? Я вижу общее описание как "Стек создан в верхнем уровне-адресе и куче на низкоуровневом адресе" . Пожалуйста, объясните это
4b9b3361

Ответ 1

"Стек создается на верхнем уровне-адресе, а куча на низкоуровневый адрес" Пожалуйста, объясните это

Это миф. Это может быть основой исторической правды. Иногда это может резонировать с вещами, которые вы видите в реальной жизни. Но это не буквально верно.

Это достаточно легко изучить, хотя:

#include <stdlib.h>
#include <stdio.h>

void check(int depth) {
    char c;
    char *ptr = malloc(1);
    printf("stack at %p, heap at %p\n", &c, ptr);
    if (depth <= 0) return;
    check(depth-1);
}

int main() {
    check(10);
    return 0;
}

На моей машине я вижу:

stack at 0x22ac3b, heap at 0x20010240
stack at 0x22ac0b, heap at 0x200485b0
stack at 0x22abdb, heap at 0x200485c0
stack at 0x22abab, heap at 0x200485d0
stack at 0x22ab7b, heap at 0x200485e0
stack at 0x22ab4b, heap at 0x200485f0
stack at 0x22ab1b, heap at 0x20048600
stack at 0x22aaeb, heap at 0x20048610
stack at 0x22aabb, heap at 0x20048620
stack at 0x22aa8b, heap at 0x20048630
stack at 0x22aa5b, heap at 0x20048640

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

Btw, моя функция check является хвостовой рекурсивной, а на некоторых реализациях с некоторыми параметрами компилятора вы можете видеть, что стек не перемещается вообще. Что говорит вам о том, почему стандарт не определяет, как все это работает, - если бы оно это сделало, это могло бы непреднамеренно запретить полезные оптимизации.

Ответ 2

Как уже упоминалось, размеры зависят от ОС. Напр. на окнах с использованием Visual Studio размер стека по умолчанию составляет 1 МБ

msdn

В Linux следующая команда может показать ваше текущее.

ulimit -s or -a

В моем 64-битном ядре Linux он показывает 8192 КБ.

Каждая программа, загруженная в память, имеет несколько сегментов. В сборке можно указать каждый из тех, кто использует префикс .data,.code и т.д. (Intelx86).

Это сегмент данных, который имеет несколько подсекций. Как стек, так и куча являются частью его в дополнение к нескольким другим.

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

Когда вызов функции возвращается, эта запись активируется и стек сжимается.

В отличие от этого куча растет с противоположного направления и содержит всю динамически выделенную память.

Причина, по которой эти два сегмента растут в противоположном направлении, состоит в том, чтобы максимизировать использование их объединенной памяти. Обратите внимание, что, как упоминалось в комментариях, это не стандарт c, но наиболее распространенная ОС реализована.

------ стек начинается ----------- стек растет вниз

-------- Если они не пересекают друг друга, программа работает нормально.

------- начинается куча ------------ куча растет вверх

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

Другие части сегмента данных - это BSS и т.д., которые могут содержать такие поля, как неинициализированные статические переменные

Ответ 3

Каков первоначальный размер, с которым создается стек/куча? и кто его решает?

Это зависит от компилятора и ОС.

В какой физической памяти они созданы? Я вижу общее описание как "Куча создана в верхнем уровне-адрес и стек на низкоуровневом адресе".

Это зависит от компилятора и ОС.

Действительно. Стандарт языка не задает минимальный размер стека и не указывает местоположение стека или кучи в памяти. И причина этого в том, чтобы сделать программы C менее зависимыми от этих деталей и, следовательно, более переносимыми на разные платформы (читайте: разные ОС, разные процессоры, разные компиляторы).

Ответ 4

Прежде всего, стандарт C не налагает никаких требований относительно того, как стек/куча реализуется Платформа.

What is the initial size with which a stack/heap is created? and who decides it?

Как правило, фиксированный размер стека выделяется для каждого процесса ОС, который зависит от платформы. Там нет ограничений на размер кучи, программа обычно имеет все доступное виртуальное адресное пространство.

Wherein physical memory are they are created?

Это специфичная для платформы. Обычно стек растет вниз, а куча растет вверх.