Почему стек не очищается и происходит "Ошибка сегментирования"?

#include <stdio.h>

void s()
{
  double f[1000000] = {0.f};
  getchar();
}

int main(void)
{
  s();
  
  double e[90000] = {0.f};
  getchar();

  return 0;
}

Почему?

Ошибка сегментирования (стек памяти сброшен на диск)

Ведь после того как отработает функция стек снова свободен, почему он не очищается?

int main(void)
{
  {
    double e[90000] = {0.f};
  }
    
  s();

  getchar();

  return 0;
}

Так тоже не работает.

И ещё, я раньше думал что используя маленькие типы данных как short и char я буду экономить память но ведь это не так. Мы мало что экономим, ведь если память под стек выделяется с созданием потока и она фиксированного размера(уже выделено какое то количество и от создания переменно ничего не убудет), то какой смысл не использовать везде int или если не хватает long long? Процессор с ними работает быстрее и память не заполниться ведь это стек, он потом очиститься

Как экономить память? Единственно что приходит на ум то что "тратят" память глобальные и статические переменные/массивы и строки(хоть создавай массив строк или используй указатель, возвращай функцией, да просто выведи printf-ом все равно будут static в read-only сегменте. Ну и malloc


Ответы (1 шт):

Автор решения: AlexGlebe

Размер стека скорее всего у вас 8 мегабайт. В начале функций выделяется место в стеке для всех переменных заранее. (Для экономии размера кода и времени.) В конце каждой функции указатель на вершину стека возвращается назад.

#include <stdio.h>

void s()
{

// в начале функции выделяется в стеке память для f : + 8000000 байт

  double f[1000000] = {0.f};
  getchar();

// в конце функции освобождается в стеке память : - 8000000 байт

}

int main(void)
{

// в начале функции выделяется в стеке память для e : + 720000 байт

  s();
  
  double e[90000] = {0.f};
  getchar();

// в конце функции освобождается в стеке память : - 720000 байт

  return 0;
}

Чтобы экономить память стека нужно переменные переносить в функции. Стек очищается после завершения функций.

#include <stdio.h>

void s()
{

// в начале функции выделяется в стеке память для f : + 8000000 байт

  double f[1000000] = {0.f};
  getchar();

// в конце функции освобождается в стеке память : - 8000000 байт

}

void fe(){

  // в начале функции выделяется в стеке память для e : + 720000 байт

  double e[90000] = {0.f};
  getchar();

  // в конце функции освобождается в стеке память : - 720000 байт

  }

int main(void)
{

  s();
  
  fe();    

  return 0;
}

В этом случае в main не выделяется заранее место в стеке на 720000 байт. Это происходит только при вызове функции fe.

→ Ссылка