2012-06-22 2 views
4

Следующее объяснение вопроса о названии в порядке, позвольте мне объяснить мой сценарий.Устранены ли адреса памяти в куче?

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

Многие объекты в списке содержат указатели на другие объекты в том же списке.

Перед тем, как разыменовать любой из этих указателей, я хотел бы использовать функцию CheckAgainstList(ptr*), чтобы убедиться, что один объект указывает на другой объект в том же списке и поэтому не указывает на объект, который с тех пор был удален.

Получите ваши шляпы tinfoil сейчас, это возможно?

  1. Объект А имеет указатель на объект B с адресом памяти 0x00988e50.
  2. Объект B удален.
  3. Объект C создан и помещается во вновь освобожденное пространство памяти 0x00988e50.
  4. CheckAgainstList(ptr*) возвращает true, когда мы проверяем указатель, потому что объект C находится в списке и находится в том же адресе памяти B, который использовался для занятия.

Теперь у нас есть ошибка, потому что A считает, что у нее указатель на B, но B ушел, и C занял свое место так сказать.

Возможна ли эта потенциальная ошибка?

+2

Не просто возможно - его вероятность. Если вы освободите B и выделите C сразу после того, как это будет возможно с множеством реализаций кучи, вы получите тот же самый буфер обратно. –

+0

Пришел сюда погулять по тому, как часто это происходит, после того, как куски памяти явно используются повторно (для данных того же типа). Так да :) – mlvljr

ответ

4

Да, эта ошибка вполне возможна.

В основном, что вы делаете, довольно опасно и приведет к ошибкам довольно быстро. Возможно, вам будет лучше использовать ссылку, подсчитанную smart ptr. C++ 11 включает std :: shared_ptr, что означает, что вы можете использовать вместо обычного указателя. Таким образом, память не будет освобождена до тех пор, пока все не закончится с ней и не уменьшит проблемы, подобные описанию.

Ваш единственный другой вариант - просканировать все остальные объекты, чтобы увидеть, ссылаются ли они на удаленные «B» и делают что-то вроде «null» из своих указателей на указатель, теперь удаленный, указатель.

4

Адреса памяти повторно используются - в зависимости от операционной системы. В противном случае, если в программе много распределений и освобождений, больше, чем в ОЗУ, это не будет продолжаться.

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

1

Ошибка более вероятна, если вы создаете только один тип объекта. Но это всегда возможно.

6

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

Проблема, которую вы пытаетесь решить, может быть под вопросом weak_ptr, которая может быть проверена на предмет действительности до ее использования.

0

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

Смежные вопросы