[英]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());
});
任何人都可以向我解釋這個嗎?
我知道答案,但我不喜歡它。 我認為這可能是鏗鏘的缺陷。
std::sregex_token_iterator
正在保存指向正則表達式的指針。
在第一個版本中,在構造splitter
之后,將破壞匿名std::regex
對象。 這會使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);
}
構造__position_
類型std::regex_iterator
:
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
對象相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.