#c #vector #data-structures #stack
Вопрос:
Я пытаюсь создать функцию для проверки проблемы с круглыми скобками, эта функция хорошо работает на моей машине, но она вызывает ошибку «переполнение буфера кучи» на машине с кодом leet, когда я вызываю vector.pop_back(). Вот код:
int isValid(string s){
vector<char> st;
for(int i = 0; i < s.length(); i ){
if(s[i] == '(') st.push_back(s[i]);
else{
if(st.back() == '(') st.pop_back(); //this line triggered the error
else return 0;
}
}
return (st.size() == 0);
}
Я уже решил эту проблему, изменив вектор на строку, но мне все еще интересно, как это могло произойти, кто-нибудь объяснит?
Ответ №1:
Вызов std::vector::back() для пустого вектора является неопределенным поведением.
Обратный вызов пустого контейнера вызывает неопределенное поведение.
(То же самое относится и к std::vector::pop()
, но в этот момент ваша программа уже находится в недопустимом состоянии, если контейнер был пуст).
Таким образом, выражение st.back() == '('
в вашем коде может привести к недопустимому состоянию программы, поскольку контейнер st
не уверен, что он не пуст.
Ваш путь к коду должен проверить пустоту контейнера перед вызовом std::vector::back()
; что-то вроде:
if (!st.empty() amp;amp; st.back() == '(')
st.pop_back();
else
return 0;
Бонусное примечание: приведенный выше код использует оценку короткого замыкания логических операторов. Это означает, что второй операнд (т. е. выражение st.back()
) не будет вызван, если контейнер пуст.
Комментарии:
1. Спасибо, это решилось таким образом, но как это может не вызвать ошибок на моей машине?
2. Технически говоря, неопределенное поведение переводит вашу программу в неизвестное состояние. Отсюда : «неопределенное поведение — нет никаких ограничений на поведение программы».. Мы привыкли говорить, что «все может случиться» (теоретически ваша программа может даже стереть ваш жесткий диск, никаких гарантий относительно ее поведения не предоставляется). На практике поведение меняется по-разному для разных сред (компилятор, аппаратная архитектура, стандартная библиотека,…). На вашей машине «плохое состояние» не видно, но в любом случае присутствует.
Ответ №2:
возможно, потому, что вы не назначили какой-либо элемент в векторе перед проверкой условия if. Попробуйте положить :
if(st.size()!=0)
{
if(st.back() == '(') st.pop_back();
else return 0;
}
на этом фрагменте кода