Другие языки программирования и технологии

С++ куча и new\delete

В С++ оператор new на самом деле не выделяет память, а только размещает её в кучу. То есть говорит компилятору, что "эта память - программиста, и он сам ее освободит, когда захочет". То есть нет никого выделения памяти, да? А память, как бы, заранее формально поделена на память, которой управляет компилятор (стек) и память, которой управляет программист (куча) , а по умолчанию память - стековая, а new - отправляет память в кучу. То есть написав new - ты на самом деле пишешь "Это моя память, если захочу ее очистить - воспользуюсь delete" Я правильно всё понял?
>на самом деле не выделяет память, а только размещает её в кучу.. . То есть нет никого выделения памяти, да?
В куче. И размещение в куче и называется выделением. Проблема в названии, не в действии.

>То есть говорит компилятору

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

>Я правильно всё понял?

Все остальное - правильно.
Влад Сапрыкин
Влад Сапрыкин
96 745
Лучший ответ
создается стек с зарезервированным объемом памяти, которая увеличивается или уменьшается в процессе использования. . программно запрашивает размер памяти, а система аппаратно выделяет ее с пометкой, что это данные и именно для этого поцесса.. . а вообще есть понятие виртуальная память и физическая. виртульная как правило больше физической. . и работа происходит с дескрипторами виртульаной памяти. . а все остальное происходит на аппаратном уровне...
Читай про диспетчер памяти, ведь полно статей на эту тему, а здесь писать большую простыню кусками нет смысла вообще.

>tania duke "который сам проверяет размеры и делает нужный вызов за говнокодера"
Ха-ха, умная нашлась, сможешь поддерживать машино-зависимый код как делает стандарт, даже разработчики POSIX отказались от этого, конечно в Linux есть brk, mmap/unmap...

p.s. Вот что не нравится в IT-woman, то что полно амбиций, без обид.
На самом деле все куда более интересней.
Возьму пример x86 и современных ОС типа GNU/Linux. Ясное дело, что есть виртуальная память, разделение времени и тп. Виртуальная память и страничная модель здесь ключевой механизм. Если кратко - страница блок памяти физического размера, который может быть замещен во время исполнения (смотри подкачку страниц) . И так - виртуальная память, если кратко - механизм, при котором область памяти процесса отображается на физическую однонаправленно. Процесс может использовать только свою область памяти (а не всю ОЗУ) , и в случае обращения по невыделенному адресу в ЕГО ВИРТУАЛЬНОМ (начиная с 0x0) адресном пространстве или попытки записи в страницу памяти, которая помечена как RO (readonly), например область кода разделяемой библиотеки, он будет завершен аварийно (смотри general protection fault). О механизме замещения страниц и PageFault почитаете сами (пишу кратко) .

При создании процесса происходит размещение его исполняемого кода, стека, области данных в памяти. Происходит создание PTE, создание локальной таблицы дескрипторов LDT, а также инциализация контекста: информации о процессе, PCB. Как стает очевидно и понятно ему выделяется фиксированное число страниц => фиксированный размер памяти. Далее образ процесса загружается в память. Память процесса делится в Linux на сегменты: сегмент кода (text), сегмент данных (data и bss) для локальных переменных, сегмент стэка (stack) и место под кучу для размещения PTE-адресов кучи (heap). Далее процессу передается управление на определённое системным планировщиком время. Если процесс захочет получить память, то он производит системный вызов типа mmap или brk (последний только меняет границу сегмента данных и применяется при малых аллокациях в пределах страницы) , который обрабатывает ядро, выделяя ему свободные страницы памяти !!заметьте, память выделяется ПОСТРАНИЧНО!! . Создается запись PTE и процессу возвращается управление (или же управление с нулевым указателем в ответе, если страничек свободных нет то в PFN). На практике в языке C этому действию отвечает функция стандартной библиотеки (libc) под названием malloc (который сам проверяет размеры и делает нужный вызов за говнокодера) , в C++ это new. Если процесс хочет освободить ранее выделенную память он либо уменьшает границу через brk или же отмапливает память через munmap (это уже делает free или delete в С++). Вот и вся механика, если кратко.