此代码取自IncludeOS github page。我修改了一下,这样它就可以在没有其他头文件的情况下编译。来自IncludeOS的find
函数有点太冗长,所以我想简化它。但修改后,代码的行为与我所期望的不同。铛++内存消毒剂报告使用未初始化值
这里是一个简短的解释。此代码用于解析HTTP标头。标题字段是名称 - 值对。它代表vector<pair<string, string>>
。 find
函数用于查找标题中的字段名称的位置,并且has_field
用于检查标题中是否存在特定的字段名称。
在main
函数中,四个元素被添加到字段。 six
不应在fields.But has_field
返回true。
我试图跟踪gdb
的错误。但是我在输出的海洋中迷失了。我确实发现了一些有趣的信息。
的std :: __ uninitialized_copy <假> :: __ uninit_copy < __gnu_cxx :: __ normal_iterator <的std ::对<的std :: __ cxx11 :: basic_string的<炭的std :: char_traits <炭>,性病::分配器<炭> >,性病:: __ cxx11 :: basic_string的<炭的std :: char_traits <炭>,性病::分配器<炭> > >常量*,性病::矢量<的std ::对<的std :: __ cxx11 :: basic_string的<焦,标准:: char_traits <焦炭<,性病::分配器<焦炭> >,性病:: __ cxx11 :: basic_string的<焦,标准:: char_traits <焦炭>,性病::分配器<焦炭> > > ,性病::分配器<的std ::对<的std :: __ cxx11 :: basic_string的<炭的std :: char_traits <炭<,性病::分配器<炭> >,性病:: __ cxx11 :: basic_string的<炭,标准: :char_traits <char>,std :: allocator <char> > > > > >,性病::对<的std :: __ cxx11 :: basic_string的<炭的std :: char_traits <炭>,性病::分配器<炭> >,性病:: __ cxx11 :: basic_string的<炭,标准:: char_traits <炭>,性病::分配器<炭> > > > *(__first = {第一= “一”,第二= “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