【发布时间】:2015-06-19 02:45:51
【问题描述】:
我很难理解为什么下面的代码会产生分段错误。没有 myMap["0"] = 53;该程序将运行得很好。似乎当我尝试使用 std::map 和 std::string 作为键时,由于 LLVM 库中的一些冲突,程序将崩溃。但是,如果键类型是字符串以外的任何其他数据类型,则程序将正常执行。
我的印象是,即使 llvm 库使用带有字符串键的 std::map,由于 mapped_type 不同,也会生成不冲突的映射模板。那么这个错误怎么可能呢?
#include <string>
#include <iostream>
#include <IR/Module.h>
#include <IRReader/IRReader.h>
#include <Support/SourceMgr.h>
#include <IR/LLVMContext.h>
#include <memory>
#include <map>
using std::string;
using std::cout;
using std::endl;
using std::unique_ptr;
using llvm::Module;
using llvm::LLVMContext;
using llvm::SMDiagnostic;
std::map<std::string, int> myMap;
int main(int argc, char** argv)
{
myMap["0"] = 53; // With this line included the program will seg fault
string sFilePath = "varChange.ll";
LLVMContext &Context = llvm::getGlobalContext();
SMDiagnostic Err;
unique_ptr<Module> module = parseIRFile(sFilePath.c_str(), Err, Context);
cout << "Happily Exited" << endl;
return 0;
}
这里是 seg 错误的 valgrind 输出:
Conditional jump or move depends on uninitialised value(s)
__memcmp_sse4_1 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
std::string::compare(std::string const&) const (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
bool std::operator< <char, std::char_traits<char>, std::allocator<char> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (basic_string.h:2571)
std::less<std::string>::operator()(std::string const&, std::string const&) const (stl_function.h:235)
std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::_M_lower_bound(std::_Rb_tree_node<std::pair<std::string const, std::string> >*, std::_Rb_tree_node<std::pair<std::string const, std::string> >*, std::string const&) (stl_tree.h:1141)
std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::lower_bound(std::string const&) (stl_tree.h:879)
std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::lower_bound(std::string const&) (stl_map.h:864)
std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::operator[](std::string&&) (stl_map.h:481)
llvm::AttrBuilder::addAttribute(llvm::StringRef, llvm::StringRef) (Attributes.cpp:1055)
llvm::LLParser::ParseFnAttributeValuePairs(llvm::AttrBuilder&, std::vector<unsigned int, std::allocator<unsigned int> >&, bool, llvm::SMLoc&) (LLParser.cpp:939)
llvm::LLParser::ParseUnnamedAttrGrp() (LLParser.cpp:882)
llvm::LLParser::ParseTopLevelEntities() (LLParser.cpp:245)
【问题讨论】:
-
为什么这个
std::map<std::string, int> myMap;需要是一个全局变量? -
如果你在 main 中只有地图的代码,你还有段错误吗?
-
它不需要是全局的,这只是我在一段更大的代码中找出冲突后创建的一个示例 sn-p。在地图之前是类中的数据成员。如果我删除 parseIRFile 行而不是 myMap["0"] = 53;程序将正确执行。
-
我怀疑您的代码中潜伏着另一个内存错误,但如果没有该行,它只会发生从未使用过的垃圾内存。您是否尝试在没有该行的情况下运行 valgrind?
-
@LPierce 分而治之。删除除标准 #include 标头之外的所有代码。从
main中删除所有代码,地图声明除外。代码现在可以运行了吗?如果是这样,慢慢添加代码,直到问题出现。