@Acaunt

Уменьшается ли используемая память программы?

Недавно случайно обнаружил, что если написать например так:
#include <iostream>

int main {
    { int a = 5; }
    std::cout << a;
    return 0;
}
То это выдает ошибку о том что переменной "a" не декларирована в области видимости (или что-то типо того)
Я понял, что так можно например создать временную вспомогательну переменную, и когда код выйдет из {}, то переменная очистится и память требуемая программе уменьшется.
Вопросы:
• "Я правильно понял это?"
• "Стоит ли на практике такое делать?"
• "Если да, то как лучше оформлять это в коде для читабельности?"
  • Вопрос задан
  • 145 просмотров
Решения вопроса 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Не гарантированно, но в некоторых случаев компилятор действительно сможет переиспользовать место на стеке под переменную a для какой-то новой локальной переменной, когда a выйдет из зоны видимости. Но чаще это место просто будет пустым до конца функции и никакой экономии памяти вы не получите.

Но вообще, делать так для экономии памяти никогда, категорически не рекомендуется. Код становится менее читаем а экономите вы на спичках. Это локальные переменные - они на стеке. Их много можно выделить только рекурсией или большими массивами (ну не объявите вы в коде миллион локальных переменных). В обоих случаях, если стека не хватает - надо или избавлятся от рекурсии/больших массивов изменением логики, или выносить их в кучу.

Использование фигурных скобок для ограничения зоны видимости переменной действительно используется на практике, когда вам надо ограничить время жизни переменной и добиться вызова деструктора в определенное время. Так делают, например, когда захватывают мютекс в многопоточных программах - специальный класс-обертка в конструкторе его хватает, в деструкторе освобождает. И иногда не надо держать мютекс во всей функции, а только в определенном месте. Допустим, дальше идут долгие вычисления, не требующие мютекса. Тут логично мютекс освободить. Но это должно встречаться редко. Если вам в функции надо несколько раз такое проворачивать, то надо ее отрефакторить и разбить на части.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
bingo347
@bingo347
Crazy on performance...
Во-первых, размер стека фиксирован, стек выделяется в момент запуска потока.
Во-вторых, компилятор и сам достаточно умный, чтобы переиспользовать стек под разные переменные использование которых не пересекается.
В-третьих, экономия на спичках, а читаемость ухудшается.

P.S. такую штуку действительно иногда используют, но ради того чтоб вызвать деструктор в нужной точке кода.
Ответ написан
Комментировать
vabka
@vabka
Токсичный шарпист

Стоит ли на практике такое делать?

В некоторых случаях это действительно полезно.


Если да, то как лучше оформлять это в коде для читабельности?

По возможности - лучше не применять.


то переменная очистится и память требуемая программе уменьшется

Нет, не очистится. Она же на стеке - под нё уже заранее заготовлено место.

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

Ну и в случае с одним int это будет байта четыре - что вообще очень смешной объём памяти по сравнению с 16мб*, которые выделяются на стек потока.

* Цифра не точная, может зависеть от ОС и её настроек.
Ответ написан
Комментировать
Alexandroppolus
@Alexandroppolus
кодир
Это переменная на стеке, не в куче. О стеке стоит начинать беспокоиться, если у тебя здоровенная рекурсия, но тогда лучше сразу, от греха подальше, переписать алгоритм на цикл
Ответ написан
Комментировать
@dima20155
you don't choose c++. It chooses you
Сама переменная в фигурных скобках бесполезно.
А если вы проводить какие-то манипуляции с переменными в отдельной области видимости, то это и есть то, что делают функции. Да, действительно, если все функции напрямую вставить в поле main и получить спагетти код, то помимо того, что у вас потребуется значительно больше памяти на стеке, так ещё вы будете хранить кучу ненужных переменных. К слову, стек имеет размер около 1МБ, что как вы догадыветесь только в контексте микроконтроллеров много.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы