【问题标题】:c++ maps value get corruptedc ++地图值损坏
【发布时间】:2013-10-30 15:53:02
【问题描述】:

我创建了一个多图 ErrorMap 并插入这样的值

map<char*,char*> ErrorMap;
ErrorMap.insert(map<char*, char*>::value_type(*l_itrList, ErrorMsg1));

在此之后,我正在阅读此地图三遍以处理一些请求。在删除之前,我打印地图,前两个对值已损坏,其余值正常。

我在这里得到核心转储。

我能否详细了解这些值在阅读时有何影响?任何解决方案,以便我可以保存我的地图,直到我明确删除它。

我的日志

mapItrMov4.first (€J+) mapItrMov4.second(无效的服务请求)

mapItrMov4.first (hK+) mapItrMov4.second(无效的服务请求)

mapItrMov4.first (first) mapItrMov4.second (InvalidServiceRequest)

....

之后就好了

gdb 回溯

(gdb) bt

0x001c2cae in raise() from /lib/tls/i686/libc.so.6

0x001c42b0 in abort() from /lib/tls/i686/libc.so.6

0x001f2469 in __libc_message () from /lib/tls/i686/libc.so.6

0x001f7ef8 in _int_free() from /lib/tls/i686/libc.so.6

0x001f824f in free() from /lib/tls/i686/libc.so.6

0x004dbfd1 in operator delete() from /usr/lib/libstdc++.so.6

0x004dc01d in operator delete[] () from /usr/lib/libstdc++.so.6

amsAccMgmtReqHandler::opServicesReqHandler 中的 0x080ab607 (this=0x95b91dc, m_Response=0x95ba588 "68287

amsAccMgmtReqHandler::handleRequest 中的 0x080b35c4 (this=0x95b91dc, a_cpRequestStr=0x2187820 "1102000073589953099999000000000599999000"..., a_cpResponseStr=0x95ba588 "68287

amsWorker::run 中的 0x081344d5 (this=0x95b91d0)

workerThread::ThreadProc 中的 0x081cef83 (p=0x959f234)

0x003ca144 in start_thread() from /lib/tls/i686/libpthread.so.0

/lib/tls/i686/libc.so.6 中的 clone() 中的 0x00258a7e

【问题讨论】:

  • 猜测:**l_itrList*ErrorMsg1 的生命周期在地图仍然存在时结束(例如,它们是局部变量并且超出范围)。你能发布更多关于这些是什么的信息吗?
  • 你有没有使用valgrind来查找内存泄漏?
  • @Angew... 大约是 900 LOC。所以发布更多代码是不可能的。甚至我也不知道这些价值观在哪里影响。所以我不知道我需要在这里发布哪个部分。
  • 但是gdbvalgrind 是互补的。您应该同时使用这两种方法,因此请尝试valgrind(使用起来非常简单)。另外,使用g++ -Wall -g 编译(也可以尝试-WextraClang ....)
  • 感谢您的更新。我几乎可以向您保证,地图没有按照您的想法行事,而且很可能不符合地址比较标准,因为它使用默认的 std::less&lt;&gt; 比较器很可能不是来自相同分配的连续内存区域的原始指针。请改用std::map&lt;std::string,std::string&gt;。如果没有自定义比较器和使用经过深思熟虑的计划的工程师,原始指针会产生 糟糕的 映射键,并且通常是错误的想法。

标签: c++ linux map


【解决方案1】:

我的猜测是因为你的地图类型是&lt;char*, char*&gt;,所以当你阅读它的时候,指针points的内容已经被deleted,并且指针变成了野指针

当地图插入时,它只是复制它的值。这意味着:如果类型是指针,它复制指针的值,但不是它指向的内容。

为什么不将类型更改为&lt;string, string&gt;? std::string 以非常低的成本处理复制,避免了指针引起的问题。

【讨论】:

  • 我认为您没有阅读我的问题。我只说了前两个值...之后我正确地得到了 10 个值...请先阅读我的问题。
  • 如果你使用map&lt;char*, char*&gt;,事情可能仍然有效,这取决于内存的管理方式,所以仅仅因为它偶尔有效,并不意味着它是正确的。
【解决方案2】:

所以我将假设ErrorMap 的类型是map&lt;char*, char*&gt;,因为您使用该类型的value_type 进行插入。

你写map&lt;char*的那一刻你就已经输了。您会遇到内存管理问题,此外您没有得到正确的排序,因为它将按指针值而不是字符串值排序。而且它不是 const 安全的,因为它不会阻止您修改键指向的内容,这是破坏地图的另一种绝妙方式。

只需使用map&lt;string, string&gt; 即可摆脱一堆麻烦。

【讨论】:

    【解决方案3】:

    我得到了答案。可能你们都是对的,但我的方法不同。正如我所料,当人们不知道他们过去那样做的答案时,我投了反对票。

    我的回答是我在向map key 提供值时使用iterator。一段时间后,我从这个iterator 中提取了值。当我得到值时,我正在从地图中删除一些值(在不知不觉中),这就是我的问题。连续打印日志后,我得到了答案。

    无论如何,感谢您的回复和努力。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-03
      • 2011-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多