gpt4 book ai didi

c++ - 现场创建对象与变量声明

转载 作者:太空狗 更新时间:2023-10-29 21:00:13 25 4
gpt4 key购买 nike

我有以下代码(将字符串拆分为 vector ),在 for_each 循环的第二次迭代中出现段错误:

std::string command = "Something something something";
std::sregex_token_iterator splitter {command.begin(), command.end(), std::regex{"\\s+"}, -1};
std::sregex_token_iterator splitter_end;
std::for_each(splitter, splitter_end, [&](std::ssub_match sm) {
cmd.push_back(sm.str());
});

为了了解发生了什么,我将正则表达式的声明分离为命名变量,它开始工作:

std::string command = "Something something something";
std::regex rx {"\\s+"};
std::sregex_token_iterator splitter {command.begin(), command.end(), rx, -1};
std::sregex_token_iterator splitter_end;
std::for_each(splitter, splitter_end, [&](std::ssub_match sm) {
cmd.push_back(sm.str());
});

谁能给我解释一下?

最佳答案

我知道答案,但我不喜欢它。我认为这可能是 clang 的一个缺陷。

std::sregex_token_iterator 正在保存指向正则表达式的指针。

在第一个版本中,匿名std::regex 对象在构造splitter 之后被销毁。这使 splitter 指向内存中已释放的空间。

在第二个版本中,rx 将一直存在到 block 结束。这使 splitter 指向正确的对象。


std::regex_token_iterator 构造函数

template <class _BidirectionalIterator, class _CharT, class _Traits>
regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::
regex_token_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
const regex_type& __re, int __submatch,
regex_constants::match_flag_type __m)
: __position_(__a, __b, __re, __m),
_N_(0),
__subs_(1, __submatch)
{
__init(__a, __b);
}

构造 std::regex_iterator 类型的 __position_:

template <class _BidirectionalIterator, class _CharT, class _Traits>
regex_iterator<_BidirectionalIterator, _CharT, _Traits>::
regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
const regex_type& __re, regex_constants::match_flag_type __m)
: __begin_(__a),
__end_(__b),
__pregex_(&__re),
__flags_(__m)
{
_VSTD::regex_search(__begin_, __end_, __match_, *__pregex_, __flags_);
}

这是在指针中存储 __re 的地址。一旦 __re 超出范围,__re 就会被破坏 __position_ 会留下一个悬空指针。


最后的说明

以下作品:

std::string command = "Something something something";
std::for_each(std::sregex_token_iterator{command.begin(), command.end(), std::regex{"\\s+"}, -1},
std::sregex_token_iterator{},
[&](std::ssub_match sm) {
cmd.push_back(sm.str());
});

这是因为匿名 std::regex 的生命周期与匿名 std::sregex_token_iterator 对象相同。

关于c++ - 现场创建对象与变量声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22588768/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com