Невозможно увеличить возвращаемый sregex_iterator? - PullRequest
0 голосов
/ 23 октября 2019

Я пытаюсь создать sregex_iterator из некоторых сложных вычислений, поэтому я написал функцию, чтобы сделать это и вернуть итератор. Однако когда я затем хочу увеличить возвращаемый итератор, программа падает, иногда выдает std :: bad_alloc, иногда нет ..

Мне удалось сократить его до MWE с небольшим кодом, но каким-то образом я все еще не могу понятьчто происходит ..

#include <iostream>
#include <regex>

using namespace std;

sregex_iterator get_it(const string& str) {
    regex r("([ab]{3})");

    auto it = sregex_iterator(str.begin(), str.end(), r);
    cout << (it == sregex_iterator() ? "end\n" : "more\n");
    ++it; //works as expected .. no crash. When commented out, program still crashes
    cout << "can incr ..\n";

    return it;
}

int main(int argc, char** argv) {
    auto it = get_it("aaa bbb");
    cout << (it == sregex_iterator() ? "end\n" : "more\n");
    ++it; //this crashes the program

    cout << "success\n"; // never runs
}

Для компиляции я использую g ++ (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) 7.4.0 с флагом -std=c++11.

Это запускает и выводит

more
can incr ..
more
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

Таким образом, приращение работает в функции, где я создаю итератор, но не снаружи. Но все, что происходит, - это копирование (/ перемещение, если происходит RVO) итератора, что не должно сделать его недействительным? Конечно, sregex_iterator не хранит ссылку или указатель на какой-либо из своих построенных аргументов from?

Мое единственное предположение: там должен быть ref / ptr для временного хранения, но я его не вижу ... или чтоя здесь скучаю?

1 Ответ

0 голосов
/ 23 октября 2019

Очевидно, sregex_iterator хранит указатель на регулярное выражение сконструированного объекта.

Ответственность за то, чтобы объект std :: basic_regex, переданный в конструктор итератора, был передан в конструктор итератора, является обязанностью программиста. Поскольку итератор хранит указатель на регулярное выражение, приращение итератора после того, как регулярное выражение было уничтожено, получает доступ к висячему указателю.

из cppreference. Это кажется неудачным ..., но я думаю, что я могу вернуть регулярное выражение вместо итератора.

Любопытно, что регулярное выражение является C ++ 11 и не имеет конструктора перемещения, но я вижу, что это было добавлено с C++ 14 .. может быть, время для обновления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...