未初始化的值由堆分配创建:Unordered_map

时间:2014-03-04 04:31:37

标签: c++ string valgrind unordered-map

解决方案:我可以拥有庞大的字符串,然后我必须为它们保留内存。而不是使用字符串我在哈希表中使用char指针,因此我为哈希表键保留了适当的内存。

问题:

如果已经提出问题,我很抱歉,但我找不到任何帮助我的答案。

我有以下代码:

EDIT(Valgrind问题函数的主循环)

i = 0;
wordPos = 0;
for (; it != end; ++it,i++){

    // I want to ignore this element on purpose
    if (i == 1) continue;

    bool isscript;
    string tag(it->tagName());

    convertToLower(tag);

     if (it->isTag()==1){
         if (tag=="script") isscript = true;
         else isscript = false;
     }


     if (it->isComment()==0 && it->isTag()==0 && isscript==0){

         wordlist.clear();

         tokenize(it->text(),wordlist);
         int ii = 0;
         vector<string>::iterator it_palavras = wordlist.begin();         

         vector<string>::iterator it_words = wordlist.begin();
         int ii = 0;
         while(ii<wordlist.size()){
            string word(wordlist[ii]);
            convertToLower(word);

            wordsPos++;

           if (voc.find(word) == voc.end()){
              voc[word] = countwords;

              voc_inv[countwords] = words;
              term_pos[countwords] = new vector<int>();
              term_pos[countwords]->push_back(wordpos);
              countwords++;
           }else{
              if (term_pos.find(voc[word]) == term_pos.end())
                        term_pos[voc[word]] = new vector<int>();
                    term_pos[voc[word]]->push_back(wordpos);
           }
           ii++;
    }
}

voc的类型是unordered_map,但是当我在我的代码中运行valgrind时,会出现以下消息:

编辑现在我用标志--track-origins = yes粘贴完整的错误。

编辑2 现在我用标志--- dsymutil = yes粘贴完整的错误。

==21036== Use of uninitialised value of size 8
==21036==    at 0x4201FF: _platform_memcmp (in /usr/lib/system/libsystem_platform.dylib)
==21036==    by 0x10001F10D:  std::__1::__hash_iterator<std::__1::__hash_node<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>, void*>*> std::__1::__hash_table<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>, std::__1::__unordered_map_hasher<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, true>, std::__1::__unordered_map_equal<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, true>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > >::find<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) (string:642)
==21036==    by 0x10000358F: Colecao::ler_arvore_dom(tree<htmlcxx::HTML::Node, std::__1::allocator<tree_node_<htmlcxx::HTML::Node> > >, int, std::__1::unordered_map<int, std::__1::vector<int, std::__1::allocator<int> >, std::__1::hash<int>, std::__1::equal_to<int>, std::__1::allocator<std::__1::pair<int const, std::__1::vector<int, std::__1::allocator<int> > > > >&) (colecao.cpp:135)
==21036==    by 0x100002A19: Colecao::ler(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) (colecao.cpp:73)
==21036==    by 0x100001781: main (index.cpp:47)
==21036==  Uninitialised value was created by a heap allocation
==21036==    at 0x70AB: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==21036==    by 0x7528D: operator new(unsigned long) (in /usr/lib/libc++.1.dylib)
==21036==    by 0x77E12: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(char const*, unsigned long) (in /usr/lib/libc++.1.dylib)
==21036==    by 0x10001A0FF: std::__1::unordered_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, int> > >::__construct_node(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) (memory:1505)
==21036==    by 0x10000838D: std::__1::unordered_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, int> > >::operator[](std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) (unordered_map:1209)
==21036==    by 0x100003835: Colecao::ler_arvore_dom(tree<htmlcxx::HTML::Node, std::__1::allocator<tree_node_<htmlcxx::HTML::Node> > >, int, std::__1::unordered_map<int, std::__1::vector<int, std::__1::allocator<int> >, std::__1::hash<int>, std::__1::equal_to<int>, std::__1::allocator<std::__1::pair<int const, std::__1::vector<int, std::__1::allocator<int> > > > >&) (colecao.cpp:139)
==21036==    by 0x100002A19: Colecao::ler(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) (colecao.cpp:73)
==21036==    by 0x100001781: main (index.cpp:47)

当我在大量数据中运行代码时,我得到分段错误,我认为这是因为Valgrind错误。

我认为我不需要为unordered_map中的字符串保留空间,然后我发现这是单词变量构造函数中的东西。当我用静态字符串初始化单词时(例如,单词(“test”)),Valgrind停止抱怨。

我不知道如何修复此字符串/ unordered_map / memory问题。

编辑:GDB没有帮助我。只有当我使用大量数据然后使用大量内存时才会出现分段错误。 GDB给我的唯一东西就是Segmentation Fault和内存地址。 Valgrind给了我一个更完整的信息。

1 个答案:

答案 0 :(得分:2)

这实际上可能是Valgrind与您平台的memcmp()实现之间的问题(我猜想是Mac OS X吗?)。

应用程序中未初始化的值应该来自malloc()构造函数中的std::string调用,后者不可能单独“创建”未初始化的内存。所以我猜测malloc()会分配比必要更多的内存(可能与8个字节对齐),而_platform_memcmp()也会考虑这些字节。系统库通常具有此类函数的高度优化实现(memcpy,memcmp,strcpy ...)。由于Valgrind经常遇到这些优化问题,因此它提供了自己的替换函数(在mc_replace_strmem.c中)。

也许Valgrind缺少OS X memcmp()的替代品,或者你的Valgrind版本太旧了?此外,您的系统可能存在设置问题,导致Valgrind在运行时无法检测memcmp()函数(我不熟悉OS X,但您可能需要某种系统库调试信息)。

所以,有些问题:

  • 你在运行最新的Valgrind版本吗?如果没有,请升级它。
  • 你正在使用哪个OS X版本?
  • 如果在编译应用程序时禁用优化,问题是否会消失?

如果这没有帮助,您可能想要在Valgrind用户邮件列表(http://valgrind.org/support/mailing_lists.html)询问此特定问题。

顺便说一下。在没有任何行号的情况下分析Valgrind回溯非常困难。请参阅Debugging Symbols Lost When Linking?以获取有关在回溯中获取行号信息的建议(简而言之:向Valgrind命令行添加“--dsymutil=yes” - 但请先在http://valgrind.org/docs/manual/manual-core.html#manual-core.erropts中查看此选项的注释)