почему после операции pop_back () он по-прежнему печатает полный вектор? - PullRequest
1 голос
/ 26 февраля 2020

У меня есть следующая основная программа, которая создает объект Stack, заполняет его целыми числами и затем выталкивает их. Код хорошо работает, но часть pop_back (), похоже, не работает, даже после pop_back () она печатает все значения. Как это возможно?

#include<iostream>
#include<vector>
using namespace std;
int main(){

    vector<int> myVector; //initalization

    int value;
    //input in a vector using push_back
    for (int i = 0; i < 6;i++){
        cin >> value;
        myVector.push_back(value);
    }
    cout<<"Initial vector size:" << myVector.size() <<endl;

    for (int i = 0; i < 6;i++){
        cout << myVector[i];
    }
    cout << endl;
    myVector.pop_back();
    cout<<"Vector size after pop back: " << myVector.size() << endl;
    cout << endl;
    cout << "First element is: " << myVector.front() << endl;
    cout << "Last element is : " << myVector.back() << endl;
    for (int i = 0; i < 6;i++){
        cout << myVector[i];
    }
        return 0;
}

Ответы [ 3 ]

5 голосов
/ 26 февраля 2020

Все сосредоточились на том, чтобы сказать this is undefined behavior fix code, но вопрос был в том, почему это работает.

Чтобы понять, почему это работает, вы должны понять, как vector работает более или менее.

  • Вектор выделяет некоторый блок памяти для хранения элементов.
  • размер этого блока определяется емкость , которая говорит, сколько элементов может быть сохранено в векторе, без выделения нового блока памяти
  • capacity обычно больше size из vector
  • Теперь, когда вы удаляете элементы из вектора, capacity и выделенный блок памяти не изменяется. Это оптимизация.
  • когда вы удаляете элемент из спины, просто вызывается деструктор (для int он ничего не делает) и размер вектора уменьшается.
  • ваше значение не очищается, только помечается как из векторного размера
  • , поэтому, когда вы используете operator[], он не проверяет, превышаете ли вы его размер. Он просто возвращает значение по указанным c сумматорам
  • , поскольку pop_back только что уменьшенный вами размер все еще там

Обратите внимание, если вы позвоните shrink_to_fit после pop_back велика вероятность того, что будет, и с cra sh, иначе вы не получите такое же значение. Тем не менее, это неопределенное поведение, и может произойти все что угодно.

Еще один способ увидеть ваш код плохо - использовать at, который проверяет, находится ли индекс в допустимом диапазоне.

4 голосов
/ 26 февраля 2020

std::vector::pop_back функция работает просто отлично. После выполнения вызова к нему вы пытаетесь распечатать все 6 значений вместо 5. Поэтому вы получаете доступ к недействительной памяти . В вашем случае программа выводит значение, которое было удалено, но в другом случае может вывести какое-то значение мусора. Вот почему это UB - Неопределенное поведение .

Попробуйте выполнить следующее, и вы увидите, что последний элемент отсутствует в std::vector:

for (int i = 0; i < myVector.size(); i++) {
    std::cout << myVector[i];
}

или еще лучше использовать на основе диапазона для l oop:

for (auto const i : myVector) {
    std::cout << i;
}
1 голос
/ 26 февраля 2020

Проблема в том, что вы проходите oop через вектор - вы ожидаете, что в нем будет 6 элементов, даже после того, как вы удалили последний элемент. Это неопределенное поведение.

Использование диапазона на основе для было бы предпочтительным в обоих случаях, когда вы хотите вывести содержимое вектора:

for (auto i:myVector) {
    cout << i;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...