Что именно происходит при удалении my_object; выполняется? Вся остальная память смещена влево на sizeof(MyClass)?

Ради этого вопроса я буду представлять память как простой массив байтов, и я буду говорить о куче памяти, потому что ее можно динамически выделять.

Допустим, я создаю экземпляр некоторого класса и создаю объект в куче, где уже выделена некоторая память. Затем, после создания объекта, я выделяю еще немного памяти (возможно, путем создания экземпляра другого класса). Разумеется, это подразумевает использование ключевых слов new и delete.

Теперь память выглядит так:

... byte byte my_object ... my_object byte byte ...

Что именно происходит, когда выполняется delete my_object;? Вся остальная память смещена влево на sizeof(MyClass)? Если да, то кем? ОС? Что же тогда происходит, когда нет ОС, обеспечивающей виртуальную память?


person corazza    schedule 03.01.2013    source источник
comment
Спасибо за правку, Роберт, теперь стало понятнее.   -  person corazza    schedule 04.01.2013


Ответы (4)


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

Некоторые языки/среды поддерживают сжатие сборщиков мусора. Таким коллекционерам разрешено перемещать объекты, и поэтому они могут устранять дыры, если захотят. Такие подходы сложно реализовать, поскольку сборщику необходимо знать расположение каждого отдельного указателя в программе. Поэтому коллекторы этого типа больше подходят для языков более высокого уровня.

person NPE    schedule 03.01.2013

Если бы память была смещена, это была бы довольно плохая ОС IMO. Как правило, ОС уведомляется о том, что эта память доступна для повторного использования. Его даже не требуется очищать (и в большинстве случаев это не требуется). Когда память больше не может быть выделена, вы обычно получаете исключение (если вы используете new) или обратный указатель NULL (если вы используете malloc).

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

person Luchian Grigore    schedule 03.01.2013

Память не смещена влево. Представьте, что было бы, если бы это было так. Все эти указатели "справа" станут недействительными.

person s.bandara    schedule 03.01.2013

В типичной реализации (например, без движущегося сборщика мусора) ничего не будет перемещено.

Bames53 говорит, что Херб Саттер говорит, что стандарт говорит, что автоматическое перемещение выделенных объектов является незаконным. Спасибо, Беймс53.

person Zuu    schedule 03.01.2013
comment
Сжатие (или иное перемещение) сборщиков мусора не разрешено в C++. - person bames53; 04.01.2013
comment
Спецификация C++ требует, чтобы значения указателя были стабильными. Например, если какой-то трюк используется для сокрытия указателя, чтобы сборщик мусора не мог с ним возиться, при извлечении исходного значения указателя он все равно должен указывать на исходный объект. herbsutter.com/2011/10/25/garbage-collection -краткий обзор-и-c - person bames53; 04.01.2013