C ++ - Утечки памяти: где хранится указатель (мета) информация? - PullRequest
8 голосов
/ 03 апреля 2011

Это основной вопрос, на который я не могу найти никакого ответа.

При следующем коде произойдет утечка памяти:

   int main(){
          A* a = new A();
          // 1
     } 
     //2

Допустим, что получил значение 1000. То есть адрес 1000 в куче теперь берется объектом А.На 1, а == 1000 и на 2 а выходит за рамки.Но некоторая информация отсутствует.

В реальной жизни адрес 1000 - это адрес байта в памяти.Этот байт не имеет информации о том, что он хранит ценную информацию.

Мои вопросы:

  1. кто хранит эту информацию?

  2. как хранится эта информация?

  3. какой компонент «знает», откуда и куда указывает a точекк?Как компьютер может знать, что указывает на размер (A) байт?

Спасибо!

Ответы [ 4 ]

6 голосов
/ 03 апреля 2011
  1. Эта информация хранится в вашей программе в переменной a
  2. Компилятор знает это во время компиляции.Во время выполнения только распределитель знает, что «по этому конкретному адресу sizeof(A) байты зарезервированы» - и вы не можете использовать эту информацию, вы просто должны обрабатывать эти байты, как если бы они содержали A
4 голосов
/ 03 апреля 2011

Стандарт языка не говорит.

Все, что мы знаем, это то, что если мы сделаем delete a, память снова будет освобождена.

Есть несколько вариантов, например, выделение всего, что есть sizeof (a), из определенного пула памяти с адресами от 1000 до 1000 + x. Или кто-то (язык выполнения или ОС) может где-то хранить за столом. Или что-то еще.

3 голосов
/ 03 апреля 2011

Обычно новые и удаляемые операторы реализованы поверх malloc и бесплатны, хотя эта деталь не указана. malloc и free указывают на структуру данных, которая отслеживает, какие области памяти выделены, а какие нет, и насколько велика каждая область. Искусство компьютерного программирования Кнута, том 1, содержит довольно хорошее описание нескольких конструкций распределителя.

0 голосов
/ 03 апреля 2011
  1. Адрес памяти хранится в переменной a.
  2. Он просто сохраняется как значение в стеке, как и любая другая локальная переменная.Просто старое число, указывающее на область памяти, в которой хранится объект A.
  3. Компилятор знает, что тип a равен A*.Таким образом, он знает, что объект в местоположении в a должен быть объектом A.Вот почему у вас возникают проблемы, если у вас есть другие объекты в этом месте.Сгенерированный машинный код будет действовать так, как будто объект A существует, поэтому, если его нет (возможно, там есть производный класс), он должен быть построен, чтобы иметь возможность выжить (таблицы виртуальных функций в случае производногокласс).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...