【问题标题】:Infinite loop searching C++ std::map无限循环搜索 C++ std::map
【发布时间】:2014-07-29 14:50:40
【问题描述】:

我在 C++ 中有以下方法检查地图上的名称

map<string, bool> namesMap;

bool IsValidName(const char* name) {

    string currentName(name, 16);

    if (MapContains(namesMap, currentName))
        return namesMap[currentName];
    else
        namesMap[currentName] = false;

    return false;
}


template<class T, class K>
bool MapContains(const std::map<T, K>& targetMap, const T key) {

    return targetMap.find(key) != targetMap.end();

}

调用 IsValidName() 有时会导致将线程捕获到无限循环中。我有一个内存转储,显示线程卡在 MapContains() 方法中,并进一步卡在 std::map 内部使用的 xtree 中。

应用程序中的所有名称都是 6-8 个字符长。所以这行有一个bug:

string currentName(name, 16);

这会导致所有检查名称的长度:16 而不是正确的。结果 currentName 在前 6-8 个字符中具有正确的数据,而在其余字符中具有垃圾。因此,地图充满了 16 个字符的长字符串,其中每个字符串都包含未定义的数据。

在搜索地图时,这些垃圾会导致无限循环吗?

或任何其他想法可能导致它?

更新: 正如我上面所描述的,我知道行的问题:

string currentName(name, 16);

只想知道它如何导致地图具有未定义的行为

【问题讨论】:

  • 不是解决方案,但IsValidName可以简化为string currentName = ....; return namesMap[currentName];
  • @juanchopanza 感谢您的想法。我已经对其进行了重构,但非常想找到问题的根本原因。
  • 啊...不,如果名称不存在,那将在地图中创建一个元素。
  • 未定义的行为。垃圾进,垃圾出。
  • @Jakob 这就是该方法当前所做的,以一种相当冗长的方式。

标签: c++ string map stl


【解决方案1】:

您的程序有未定义的行为

string currentName(name, 16); 行尝试从仅指向 6-8 个字符的 const char* 构建 16 个字符的字符串。


解决方案:

提供至少 16 个字符,或直接致电 string currentName(name);

【讨论】:

  • 我的印象是,作为一个例外,从未初始化的字符读取是不是 UB,只是未指定。
  • @sp2danny,不,真的是UB。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多