このコードはIncludeOS github pageから取られています。他のヘッダファイルなしでコンパイルするように少し修正しました。 IncludeOSからのfind
の機能は少し冗長すぎるので、私はそれを単純化したいと思います。しかし、変更後、コードは私が期待したものとは異なる動作をします。clang ++メモリサニタイザは、初期化されていない値の使用を報告します
ここで簡単な説明をします。このコードは、HTTPヘッダーの解析に使用されます。ヘッダーフィールドは名前と値のペアです。それはvector<pair<string, string>>
と表されます。 find
関数は、ヘッダー内のフィールド名の場所を検索するために使用され、has_field
は、特定のフィールド名がヘッダーに存在するかどうかを確認するために使用されます。
main
の機能では、4つの要素がフィールドに追加されます。 six
はfieldsに見つかりません.はtrueを返します。
私はgdb
でエラーを追跡しようとしました。しかし、私は出力の海で失われた。私はやや面白いメッセージを見つけました。
のstd :: __ uninitialized_copy <偽> :: __ uninit_copy < __gnu_cxx :: __ normal_iterator <のstd ::ペア<のstd :: __ cxx11 :: <チャーのbasic_string、STD :: char_traits <文字>、STD ::アロケータ< > >をchar型、のstd :: __ cxx11 :: <チャーのbasic_string、STD :: char_traits <文字>、STD ::アロケータ<文字> > >のconst *、のstd ::ベクトル<のstd ::ペア<のstd :: __ cxx11 ::のbasic_string <チャー、STD :: char_traits <チャー<、スタンダード::アロケータ<チャー> >、STD :: __ cxx11 ::のbasic_string <チャー、STD :: char_traits <チャー>、スタンダード::アロケータ<チャー> > > 、STD ::アロケータ<のstd ::ペア<のstd :: __ cxx11 ::のbasic_string <チャー、STD :: char_traits <チャー<、スタンダード::アロケータ<チャー> >、STD :: __ cxx11 ::のbasic_string <チャー、STD: :char_traits <char>、std :: allocator <char> > > > > >、STD ::対<のstd :: __ cxx11 :: <チャーのbasic_string、STD :: char_traits <チャー>、スタンダード::アロケータ<チャー> >、STD :: __ cxx11 ::のbasic_string <チャー、STD :: char_traits <チャー>、スタンダード::アロケータ<チャー> > > * >(__first = {最初= "1"、第二= "1"}、__last =
変数を読み取る{最初= <エラー:できません怠惰な文字列を作成するアドレス0x0、および長さがゼロでない。 >、二= ""}、__result = 0x61bf00)
私が間違っているかを調べるためにclang
消毒剤を使用していました。興味深いレポートを表示するのはメモリサニタイザだけです。ランニング、
clang++ -std=c++17 -O1 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer main.cc
/a.out
レポート、
初期化されていない値は、関数「_ZNSt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_EC2IRA6_KcRA2_S8_Lb1EEEOT_OT0_'`のスタックフレームの 'ref.tmp' の割り当てによって作成されました。
最適化レベルを-O3
に設定すると、何も表示されません。
#include <algorithm>
#include <iostream>
#include <vector>
#include <experimental/string_view>
using Headers = std::vector<std::pair<std::string, std::string>>;
using string_view = std::experimental::string_view;
Headers::const_iterator find(Headers fields, const string_view field) {
if (field.empty()) return fields.cend();
//-----------------------------------
return
std::find_if(fields.cbegin(), fields.cend(), [field](const auto _) {
return std::equal(_.first.cbegin(), _.first.cend(), field.cbegin(), field.cend(),
[](const auto a, const auto b) { return std::tolower(a) == std::tolower(b); });
});
}
bool has_field(Headers fields, const string_view field)
{
return find(fields, field) != fields.cend();
}
int main()
{
Headers fields;
fields.emplace_back("one", "1");
fields.emplace_back("two", "2");
fields.emplace_back("three", "3");
fields.emplace_back("four", "4");
std::string s = "six";
if (has_field(fields, s))
std::cout << s << " is in " << "fields" << std::endl;
return 0;
}
が初期化されていない値を知ってはいけない、しかし、あなたは値によって 'fields'をベクトルを渡すため、' has_field'は、ベクトルの異なるコピーにイテレータを比較します。 –
@BoPerssonそうです。値渡しのコンテナにイテレータを返すことは非常に間違っています。ここに関連するstackoverflowの質問です。 https://stackoverflow.com/questions/10113572/does-passing-containers-by-value-invalidate-iterators – JohnKoch