此代码取自IncludeOS github 页面。我对其进行了一些修改,以便在没有其他头文件的情况下进行编译。find
IncludeOS 的函数有点过于冗长,所以我想对其进行简化。但是修改后,代码的行为与我的预期不同。
这是一个简短的解释。此代码用于解析 HTTP 标头。标题字段是名称-值对。它表示为vector<pair<string, string>>
。find
函数用于查找字段名在表头中的位置,has_field
用于检查表头中是否存在特定字段名。
在main
函数中,四个元素被附加到字段中。six
不应该在字段中找到。但has_field
返回 true。
我试图用gdb
. 但我迷失在输出的海洋中。我确实发现了一个有点有趣的消息。
std::__uninitialized_copy<false>::__uninit_copy<__gnu_cxx::__normal_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std: :__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >> const*, std::vector<std::pair<std::__cxx11::basic_string<char, std: :char_traits<char<, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> >, std::allocator<std: :pair<std::__cxx11::basic_string<char, std::char_traits<char<, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std: :allocator<char> > >>>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*> (__first={first = "one" , 第二 = "1"}, __last=
{first = <错误读取变量:无法创建地址为 0x0 且长度非零的惰性字符串。>, second = ""}, __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;
}