当场创建对象vs变量声明
Object creation on the spot vs variable declaration
我有以下代码(将字符串拆分为向量),在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
将一直存在到块结束。这使得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
对象相同。
相关文章:
- 在将变量声明为引用时,堆在释放后使用
- 静态变量声明和定义
- 在变量声明中使用 for 循环
- 向量索引变量声明(size_t 或 std::vector<DATATYPE>::size_type)
- C++ 类型类的变量声明不命名类型?
- 将本地 OpenCV Mat 变量声明为静态以防止重新分配
- std::enable_if 更改成员 *变量* 声明/类型
- 在C++中,变量声明左侧的大括号是什么意思?
- 将变量声明为全局变量,然后声明为局部变量 -Shadowing-
- 命名空间内C++变量声明
- 将静态全局变量声明为内联有什么意义吗?
- 如何将一个变量声明为另一个变量的值
- 如何将迭代器变量声明为私有成员变量
- 没有变量声明为函数,但错误:二进制表达式的操作数无效
- 有没有人有书面证据来保证函数中参数的定义方式与普通变量声明相同?
- ClangTool 如何获取变量声明中模板参数的位置?
- 标准与显式自动推导变量声明
- C 静态变量声明怪异链接器错误
- 如何为数组成员变量声明 getter/setter
- 可视C++变量声明