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

Posted

技术标签:

【中文标题】未初始化的值是由堆分配创建的:Unordered_map【英文标题】:Uninitialised value was created by a heap allocation: Unordered_map 【发布时间】:2014-03-04 04:31:36 【问题描述】:

解决方案:我可以有很大的字符串,然后我必须为它们保留内存。我没有使用字符串,而是在哈希表中使用 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 的完整错误。

EDIT 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 中为字符串保留空间,然后我发现这是 word 变量构造函数中的内容。当我用静态字符串(例如 word("test"))初始化 word 时,Valgrind 停止抱怨。

我不知道如何解决这个字符串/unordered_map/内存问题。

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

【问题讨论】:

你为什么不详细说明这里有什么 // 还有一些代码?你现在展示的 sn-p 是一个无限循环。如果您暂时不使用它,为什么要将迭代器添加到 wordlist? 通常,使用调试信息编译代码(对于 g++:使用 -g),以获取行号。此外,“未初始化的值是由堆分配创建的”下方的 Valgrind 输出应显示未初始化值的来源 - 您也可以发布吗? 我得到了一个我没有使用的单词列表迭代器,因为我正在测试这是否是我的错误来源。在过去,我将 word 声明如下: word(*it_words) 并使用 it_words 遍历 worlist。但是 Valgrind 的错误仍然存​​在。 您能在代码中标记第 135 行和第 139 行吗?另外,您使用的各种变量(voc、wordlist、voc_inv、term_pos、countwords)的确切定义是什么?虽然可以猜测 countwords 是一个 int 而 voc 是一个 std::unordered_map,但为了调试,最好尽可能避免这种猜测。 Stack-Overflow Etiquette:不要在问题标题前加上“SOLVED”,而是应该查看答案是否适合您的解决方案,否则您应该自己编写答案。最后,接受最佳答案(不要以“SOLVED”为前缀)。考虑到我们中的一些人在您没有支付的问题上花费了时间。因此,发布解决方案是您表示感谢的最低限度。 【参考方案1】:

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

您的应用程序中的未初始化值应该来自std::string 构造函数中的malloc() 调用,后者不太可能自行“创建”未初始化的内存。所以我的猜测是 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?(简而言之:将“--dsymutil=yes”添加到 Valgrind 命令行 - 但请先查看 http://valgrind.org/docs/manual/manual-core.html#manual-core.erropts 中有关此选项的注释)。

【讨论】:

感谢您的回答。我的帖子确实缺少一些关于我的系统的信息: - 我的 Valgrind 版本已经是最新的:valgrind-3.10.0.SVN。虽然在我发布之后我在 Valgrind for mac 中发现了以下错误:bugs.kde.org/show_bug.cgi?id=326724 - 我的 OS X 是 10.9.2 (Maverick) - 我用 —dsymutil=yes 生成的信息更新了我的帖子(感谢提示!)并且即使没有优化编译,我仍然从 Valgrind 获得相同的信息。

以上是关于未初始化的值是由堆分配创建的:Unordered_map的主要内容,如果未能解决你的问题,请参考以下文章

C#基础之内存分配

VC中未分配空间的内存的处理

将对象分配到 unordered_map 数组中?

d 对象的动态建立和释放

4-数组指针与字符串1.4-动态内存分配

尝试使用未初始化的值 InceptionV3/Mixed_6d/Branch_3/Conv2d_0b_1x