вектор не может содержать указатели на недопустимую память
Вот что Стандарт должен сказать о содержимом контейнера:
(23,3): Тип объектов, хранящихся в этих компонентах, должен соответствовать требованиям CopyConstructible типов (20.1.3) и дополнительным требованиям Назначаемых типов.
(20.1.3.1, CopyConstructible): В следующей Таблице 30 T - это тип, который должен быть предоставлен программой C + +, создающей экземпляр шаблона, t - это значение типа T, а u - это значение типа const T.
expression return type requirement
xxxxxxxxxx xxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
T(t) t is equivelant to T(t)
T(u) u is equivelant to T(u)
t.~T()
&t T* denotes the address of t
&u const T* denotes the address of u
(23.1.4, Assignable): 64, T - это тип, используемый для создания экземпляра контейнера, t - это значение T, а u - это значение (возможно, const) T.
expression return type requirement
xxxxxxxxxx xxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
t = u T& t is equivilant to u
Это все, что говорится о содержании коллекции STL.В нем ничего не говорится об указателях, и в нем особо ничего не говорится о указателях, указывающих на действительную память.
Следовательно, delete
указатели в vector
, в то время как, скорее всего, очень плохое архитектурное решение и приглашение к болии страдания от отладчика в 3:00 утра в субботу вечером совершенно законны.
РЕДАКТИРОВАТЬ:
Относительно комментария Кранара о том, что «назначение указателя на недопустимое значение указателя приводит к неопределенному поведению«.Нет, это неверноЭтот код совершенно действителен:
Foo* foo = new Foo();
delete foo;
Foo* foo_2 = foo; // This is legal
Недопустимо пытаться что-то сделать с этим указателем (или foo
, если на то пошло):
delete foo_2; // UB
foo_2->do_something(); // UB
Foo& foo_ref = *foo_2; // UB
Просто создать дикий символУказатель является законным в соответствии со Стандартом.Вероятно, не очень хорошая идея, но, тем не менее, законная.
EDIT2:
Больше из Стандарта относительно типов указателей.
Так говорит Стандарт (3.9.2.3):
... Допустимое значение типа указателя объекта представляет собой адрес байта в памяти (1.7) илинулевой указатель (4.10) ...
... и относительно "байта в памяти" (1.7.1):
Основная единица хранения вМодель памяти C ++ - это байт.Байт, по крайней мере, достаточно большой, чтобы содержать любой элемент базового набора символов выполнения, и состоит из непрерывной последовательности битов, число которых определяется реализацией.Младший значащий бит называется младшим битом;самый значимый бит называется старшим битом.Память, доступная для программы C ++, состоит из одной или нескольких последовательностей непрерывных байтов.Каждый байт имеет уникальный адрес.
Здесь нет ничего о том, что этот байт является частью живого Foo
, о том, что у вас есть доступ к нему или что-то в этом роде.Это просто байт в памяти.