Действительно ли память "кучи" для каждого процесса? (или) местоположение Общей памяти совместно используется различными процессами?

Каждый процесс может использовать память "кучи", чтобы сохранить и обменяться данными в рамках процесса. У нас есть правило в программировании каждый раз, когда мы занимаем некоторое место в памяти "кучи", мы должны выпустить его, после того как задание сделано, еще это приводит к утечкам памяти.

int *pIntPtr = new int;
.
.
.
delete pIntPtr;

Мой вопрос: действительно ли память "кучи" для каждого процесса?

Если ДА,

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

Если нет,

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

Я предполагаю, что ответ на мой вопрос - ДА. Обеспечьте свою ценную обратную связь.

9
задан AKN 5 June 2015 в 13:43
поделиться

6 ответов

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

Итак, в вашем примере кода в любой современной системе, если процесс завершается до delete pIntPtr вызывается, pIntPtr все равно будет освобожден (хотя его деструктор, а не то, что у int есть, не будет вызываться.)

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

16
ответ дан 4 December 2019 в 09:35
поделиться

Обычно выделение памяти процессу происходит на более низком уровне, чем управление кучей.

Другими словами, куча создается в виртуальном адресном пространстве процесса, предоставленном ему операционной системой, и является частной для этого процесса. Когда процесс завершается, эта память освобождается операционной системой.

Обратите внимание, что C ++ не требует этого, это часть среды выполнения, в которой работает C ++, поэтому стандарты ISO не требуют такого поведения. Я говорю об общей реализации.

В UNIX системные вызовы brk и sbrk использовались для выделения дополнительной памяти из операционной системы для расширения кучи. Затем, когда процесс завершился, вся эта память была возвращена ОС.

Обычный способ получить память, которая может пережить процесс, - это разделяемая память (в операционных системах типа UNIX, не уверен в Windows). Это может привести к утечке, но большего количества системных ресурсов, а не ресурсов процесса.

2
ответ дан 4 December 2019 в 09:35
поделиться

Обычно операционная система восстанавливает любую утечку памяти при завершении процесса.

По этой причине я считаю, что для программистов на C ++ нормально никогда явно не освобождать память, которая необходима, до тех пор, пока процесс не завершится; например, любые «синглтоны» в процессе часто явно не освобождаются.

Это поведение может быть специфичным для O / S (хотя это верно, например, для Windows и Linux): теоретически не является частью стандарта C ++.

0
ответ дан 4 December 2019 в 09:35
поделиться

В большинстве современных операционных систем каждый процесс имеет свою собственную кучу, которая доступна только этому процессу и освобождается после завершения процесса - эта "частная" куча обычно используется new. Также может существовать глобальная куча (например, посмотрите на функции семейства Win32 GlobalAlloc() ), которая разделяется между процессами, сохраняется в течение всего времени работы системы и действительно может использоваться для межпроцессного взаимодействия.

3
ответ дан 4 December 2019 в 09:35
поделиться

Есть некоторые операционные системы специального назначения, которые не будут восстанавливать память при выходе из процесса. Если вы ориентируетесь на такую ​​ОС, вы, вероятно, знаете.

Большинство систем не позволяют вам получить доступ к памяти другого процесса, но опять же ... есть некоторые уникальные ситуации, когда это не так.

Стандарт C ++ справляется с этой ситуацией, не делая никаких заявлений о том, что произойдет, если вы не освободите память и затем выйдете, а также о том, что произойдет, если вы попытаетесь получить доступ к памяти, доступ к которой не принадлежит вам. Это самая суть того, что означает «неопределенное поведение», и суть того, что означает «недействительный» указатель. Есть больше проблем, чем только эти две, но они играют определенную роль.

1
ответ дан 4 December 2019 в 09:35
поделиться

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

Тем не менее, природа этого вопроса и приведенного примера требует, чтобы я с этической точки зрения указал вам и вашей команде на рассмотрение RAII.

int *pIntPtr = new int;
...
delete pIntPtr;

Этот код пахнет утечкой памяти. Если что-то в [...] выкидывает, у вас утечка памяти. Есть несколько решений:

int *pIntPtr = 0;
try
{
    pIntPtr = new int;
    ...
}
catch (...)
{
    delete pIntPtr;
    throw;
}
delete pIntPtr;

Второе решение с использованием nothrow (не обязательно намного лучше, чем первое, но позволяет разумную инициализацию pIntPtr во время его определения):

int *pIntPtr = new(nothrow) int;
if (pIntPtr)
{
    try
    {
         ...
    }
    catch (...)
    {
        delete pIntPtr;
        throw;
    }
    delete pIntPtr;
}

И простой способ:

scoped_ptr<int> pIntPtr(new int);
...

В этом последнем и лучшем Например, нет необходимости вызывать delete для pIntPtr, поскольку это делается автоматически независимо от того, как мы выходим из этого блока (ура для RAII и интеллектуальных указателей).

0
ответ дан 4 December 2019 в 09:35
поделиться
Другие вопросы по тегам:

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