Если вы просто объявляете контейнер, полный указателей на объекты, расположенные в куче, очень легко, если вы не будете осторожны, позволить контейнеру выйти из области видимости, и в этот момент у вас будет утечка памяти. Это связано с тем, что контейнер становится владельцем только того типа, который выделен в контейнере. Например, для std::vector<T*>
вектор будет поддерживать владение только распределением памяти, чтобы содержать серию указателей ... он не будет поддерживать владение объектами, на которые указывают указатели. Это просто потому, что он не может ... как контейнер узнает, что он указывает на объект кучи, а не на что-то еще? И если бы он указывал на объект кучи, откуда ему было знать, что это единственная ссылка на этот объект кучи, и он мог удалять его при необходимости и не создавать кучу свисающих указателей? Реальность такова, что контейнеры STL не несут такого рода глобальную информацию о состоянии, они не могут знать ответы на эти вопросы, и поэтому единственной памятью, управляемой контейнером STL, является память, которую он выделяет для своих собственных объектов, которые он управления. Таким образом, когда контейнер, хранящий указатели, выходит из области видимости, память, используемая для размещения указателей, будет должным образом уничтожена, но сам контейнер не будет вызывать delete
для каждого указателя, чтобы освободить объект, на который указывал каждый указатель на куча. Использование std::shared_ptr<T>
в качестве типа для контейнера STL позволяет контейнеру выходить за пределы области и удалять память, выделенную для каждого shared_ptr
, выделенного в массиве. Однако из-за информации о состоянии объекта подсчета ссылок, хранящейся в shared_ptr
, после удаления последней ссылки на объект он сам будет должным образом уничтожать объект в куче, которой он управляет. Поэтому, если у вас был контейнер STL, вышедший из области видимости, любой shared_ptrs
в этом контейнере, который был последней ссылкой на объект, на который они указывали, правильно уничтожил бы объект в куче, и вы бы не оказались в конечном итоге с серией утечек памяти из указателей, теряемых объектами кучи.