@xfnxfn

Зачем использовать кучу если есть стек? а так же где применяются указатели и ссылки?

Зачем использовать кучу если есть стек? а так же где применяются указатели и ссылки? сорри мб глупый вопрос но я только начал изучать с++.
  • Вопрос задан
  • 282 просмотра
Пригласить эксперта
Ответы на вопрос 5
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Проблема стека в том, что там лежат только локальные данные, которые исчезнут вместе с выходом из функции. Кроме того, обычно размер всех переменных на стеке известен во время компиляции. Некоторые языки умеют выделять на стеке массивы переменной длины, но даже не все C++ компиляторы так умеют. В самом стандарте языка c++ - таких масивов нет. Поэтому стек часто не подходит.

Помимо стека и кучи, есть еще глобальные переменные - но там проблема в том, что все они жестко определены во время компиляции.

Т.е. если вам нужны данные доступные вне какой-то функции, да еще их точный размер и/или количество неизвестно на этапе компиляции - вам нужно что-то кроме стека и глобальных переменных. Это и есть куча.
Ответ написан
@Mercury13
Программист на «си с крестами» и не только
Да, работа с сегментом данных и стеком значительно легче для процессора, и потому их используют везде, где можно. Куча используется в четырёх основных сценариях.
1. Выделение большого количества данных, которые стек вместить не может. Пример: матрица на много-много мегабайт.
2. Выделение не известного заранее количества данных. Обычно «не известное заранее» = «возможно, большое», но и тут есть интересный пример: даже если 1000 символов на строки нам хватает за глаза, строки используются настолько часто, что слишком уж расточительно на каждую строку пускать по килобайту.
3. Сложное время жизни объекта, не ограниченное рамками функции. Примеры могут быть в играх: функцией Spawn объект появляется, функцией Kill уничтожаем.
4. Использование виртуального полиморфизма (см. ООП). Игровые позиции, как ни странно, плохо совместимы с ООП, так что давайте будет так: функция CreateStream может создать поток, работающий с отрезком памяти или файлом.

Указатель может иметь такие значения.
• Единственная «ниточка», ведущая к объекту в куче. Все указатели перенаправили, а объект не уничтожили — всё, кусочек памяти «висит».
• Некие «стрелочки», налаженные между объектами, чтобы устроить связный список, дерево или что-то ещё. Независимо от того, какие объекты: мы вполне можем в небольшой игре создать кучу объектов с запасом, скажем, в сегменте данных или даже стеке, и налаживать между ними такое же взаимодействие, как будто они в куче.
• Просто «стрелочка» на кусок памяти, которую принимает или отдаёт функция. Причём эта стрелочка может указывать и в пустоту (nullptr). Всё, что функция изменяет по этой стрелочке, будет видеть и вызывающая программа — в отличие от передачи по значению. Или просто объект такой большой, что его копировать бессмысленно. Или архитектурно некопируемый (системный ресурс вроде открытого файла).
• Арифметика указателей позволяет работать с кучей объектов, которые сидят рядом в памяти. В Си++ есть понятие «итератор» — объект, похожий на указатель и обладающий арифметикой указателей, но позволяющий пробежаться, например, по дереву поиска.
• Опять-таки, виртуальный полиморфизм приводит к тому, что к нам приходит не-знамо-что не-знамо-какого устройства (мы лишь знаем, что этот объект, скажем, умеет читать данные как из файла) — обращаться к таким объектам можно только через указатели. В отличие от предыдущего примера с итераторами, мы не понимаем даже самых основ объекта — сколько он байтов занимает, как его создавать, копировать и уничтожать (часто в интерфейс объекта входят столь же виртуальные команды «сделать копию» и «уничтожить», но это отдельный вопрос).

На ссылку смотрите как на указатель, который 1) не может указывать в пустоту; 2) надо обязательно сразу же присвоить и дальше не перенаправлять. Самое то, когда функция принимает или отдаёт «стрелочку» на кусок памяти, и стрелочка никогда не может указывать в пустоту.
Ответ написан
Комментировать
VoidVolker
@VoidVolker
Dark side eye. А у нас печеньки! А у вас?
Затем, что это разные вещи. RTFM: куча, стек. Указатели и ссылки применяются везде.
Ответ написан
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Стек используется для хранения локальных переменных функции и адреса возврата. Если вы в функции займёте память в стеке, то после возврата из неё эта память освободится, стек вернётся к состоянию до вызова функции, использованная в функции память из стека может быть переписана следующей функцией.
Память, выделенная в куче, может использоваться разными функциями, между которыми передаётся указатель на эту память.
Ответ написан
Комментировать
mayton2019
@mayton2019
Bigdata Engineer
С точки зрения С++ есть команды new/delete которые управляют временем жизни долгоживущих
объектов. Таких как массивы примитивов и более сложные объекты из парадигмы ООП,

А для временных переменных внутри функции выгодно использовать стек. Их аллокация синхронна
с входом в функцию и деаллокация - return. Кроме того стек дает возможность вызвать функцию
из самой себя
, таким образом создавая еще один сет таких-же п еременных (это нужно для рекурсии
тоесть для погружения в глубины деревьев и графов и прочих комбинаторных задач).

Если-бы мы эти временные переменные размещали в куче - то у нас возникла бы задача очень строгого
контроля над деаллокацией. Нужно было-б гарантировать что delete сработает за мгновение до return,
а это не всегда удобно в рамках С++ кода. И это может быть причиной сложных и трудноуловимых
ситуаций с memory leak. Это когда программа в состоянии покая как будто бы начинает подъедать память
кучи безо всяких видимых оснований. Это - проблема и с этим борются.

Вообще контроль над деаллокацией памяти - это главный вопрос С++ программирования и также
показатель уровня сеньорити разработчика. На рубеже последних 10 лет немало придумано механик
как контролировать текучку памяти и созданы и всякие умные указатели и уборщики мусора и новые
языки программирования которые заявляют что якобы все проблемы с текучестью порешали.
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы