Дополнительно
Почему'т вектор::ясный удалить элементы из вектора?
Когда я использовать очистить()
на СТД::вектор
, предполагается уничтожить все элементы в "вектор", но вместо этого он не'т.
Пример кода:
vector<double> temp1(4);
cout << temp1.size() << std::endl;
temp1.clear();
cout << temp1.size() << std::endl;
temp1[2] = 343.5; // I should get segmentation fault here ....
cout << "Printing..... " << temp1[2] << endl;
cout << temp1.size() << std::endl;
Теперь, я должен был получить ошибку сегментации при попытке получить доступ к очищенной вектор, но вместо этого он заполняет в стоимость (что по мне очень глючит)
Результат выглядит следующим образом:
4
0
Printing..... 343.5
0
Это нормально? Это очень жесткий баг в месте, который в основном убил мой код в течение нескольких месяцев.
31
10
Ты не имеешь права сделать ошибку сегментации. Если на то пошло, ошибка сегментации это'т даже часть c++. Программы это удаление всех элементов из вектора, и вы'повторно незаконно доступа к контейнеру в аут. Это неопределенное поведение, а значит все может случиться. И действительно, что-то случилось.
Когда вы получаете доступ вне границ вектор, вы получите неопределенное поведение. Это значит, что все может случиться. Ничего.
Так что вы могли бы получить старое значение, мусор, или Сег-вина. Вы можете'т зависеть от чего угодно.
Если вы хотите, чтобы проверка границ, использовать на функцию-член () вместо оператора []`. Он будет бросать исключение вместо вызова неопределенное поведение.
Из cppreference:
Так что причин нет очевидной проблема в том, что вектор все-таки имеет памяти, доступной в магазине. Конечно, это лишь реализации, но не ошибка. Кроме того, как и другие ответы указывают, ваша программа имеет неопределенное поведение для доступа к очищенной содержание в первую очередь, так что технически все может случиться.
Позвольте'ы представьте, что вы'вновь богатый (возможно, вы или вы не'т ... бы то ни было)!
Поскольку вы'вновь богатый вы покупаете кусок земли на Муреа (Наветренные острова, Французская Полинезия). Вы'вновь очень уверен, что это-хороший отель, так что вы построить виллу на этом острове и жить там. Ваш вилла имеет бассейн, теннисный корт, большой гараж и даже более приятные вещи.
Через некоторое время вы оставите Муреа, поскольку вы думаете, что это'ы становятся очень скучными. Много спорта, но мало кто. Вы продаете земельный участок и вилла и решили переехать куда-то еще.
Если вы вернетесь через некоторое время вы можете столкнуться с большим количеством разных вещей, но вы не можете быть уверены даже один из них.
Кто знает? Несмотря на то, что вилла уже не принадлежит вам, вы можете даже быть в состоянии прыгать в бассейне или играть в теннис. Там также может быть другой виллой рядом с ним, где вы можете поплавать в еще больший бассейн с никто не отвлекая вас.
У вас нет никаких гарантий того, что вы'вновь гонг, чтобы обнаружить, если вы вернетесь и что's одинаково с вектором, который содержит три указатели в реализациях я'вэ посмотрел: (Имена могут быть разными, но функция в основном одинаковы.)
начало
указывает на начало выделенной области памяти (т. е. х)последний
, который указывает на последний элемент в контейнере +1 (т. е. начать+4)Позвонив очистить контейнер вполне может уничтожить всех элементов и сброс
последний = начать;
. Размер функции()
скорее всеговозвращение последнего-начать, - и поэтому вы'МР соблюдать размер контейнера 0. Тем не менее,
начало, все еще может быть в силе и все еще может быть выделено памяти ("конец" может все еще быть
начать+4`). Вы можете все еще наблюдать значения, которые вы поставили перед ясны().Оператор
[]
является эффективным, но имеет свою цену: он не выполняет проверку границ.Есть более безопасные, но эффективный способ получить доступ к вектору, как итераторы и так далее.
Если вам нужен вектор для произвольного доступа (т. е. не всегда последовательно), либо быть очень осторожны, как вы пишете свои программы, или использовать менее эффективным на()`, который в тех же условиях будет иметь исключение.
Если вы используете
вместо
вы хотели найти проблема. Рекомендуется использовать функцию В ()
и оператор
[]` не'т проверить границы. Вы можете избежать ошибок, не зная реализация вектора в STL.Кстати, я запустить свой код в мой Убунту (12.04), получается так, что вы говорите. Однако, в с Win7, это's сообщило, что "утверждения" по.
Ну, это напоминает мне типа stringstream. Если определить наказание
вы можете получить Сег вина, но это не точно, т. к. для доступа из элементов диапазона вектора оператор[]
после
очистить()вызывается перед Это просто неопределенное поведение. Из вашего поста похоже, что вы хотите попробовать, если элементы будут уничтожены, так что вы можете использовать
в` публичную функцию для этого:кроме того, после
очистить()
:http://www.cplusplus.com/reference/vector/vector/at/
попробуйте получить доступ к элементам вечерять, чем 4 что вы используете для конструктора может быть вы получите ошибку сегментации Другая идея cplusplus.com:
Очистить содержимое
Удаляет все элементы из вектора (которые разрушаются), оставив контейнер с размером 0.
Перераспределение не гарантированно произойдет, а вектор мощностей не гарантированные изменения в связи с вызовом этой функции. Типичная альтернатива, которая заставляет перераспределения является использование свопа:
вектор в<Т>().своп(х); // удалить X перераспределения
Да это нормально. ясно()
не'т гарантировать перераспределение. Попробуйте использовать размер()
послеочистить()
.в одно важное дополнение к до сих пор ответы: если класс вектор instanciated обеспечивает деструктор, то он будет вызван на поляне (и на размер(0)`, тоже).
Попробуйте это:
Эта программа скорее всего вылетит с ошибкой сегментации, но (очень вероятно) не на
типа char* данные = в[0].данных;
, но ставит строка(данные);` (использовать отладчик, чтобы увидеть).Типичный вектор реализаций оставить память, выделенная нетронутыми и оставить все как есть только после вызова деструкторов (впрочем, не факт - помню, это неопределенное поведение!). Последнее, что было сделано, было установление данных с экземпляром на nullptr, и хотя не действует в смысле языка C++/вектор, память еще есть, так что доступ к нему (незаконно) без сегментации. Это происходит, когда разыменования `типа char* указатель на данные в ставит, как null...