map<string,string>::find
似乎正在返回垃圾迭代器,因为我既不能访问my_it->first
也不能访问第二个(NB:my_it != my_map.end()
已经过验证)。 VC2010报告调试错误,并深入了解
my_it is (Bad Ptr, Bad Ptr).
'违规'地图是一个类属性_match
,如下所示:
class NicePCREMatch
{
private:
map<string, string, less<string> > _match;
public:
void addGroup(const string& group_name, const string& value);
string group(const string& group_name);
};
以下是按键返回元素的代码(注释掉的代码可以正常工作):
string NicePCREMatch::group(const string& group_name)
{
/*for (map<string, string, less<string> >::iterator j = _match.begin(); j != _match.end(); j++)
{
if(!strcmp(j->first.c_str(), group_name.c_str()))
{
return j->second;
}
}
throw runtime_error("runtime_error: no such group");*/
map<string, string, less<string> >::iterator i = _match.find(group_name);
if (i == _match.end())
{
throw runtime_error("runtime_error: no such group");
}
return i->second;
}
以下是在地图中插入新元素的代码:
void NicePCREMatch::addGroup(const string& group_name, const string& value)
{
_match.insert(pair<string, string>(group_name, value));
}
另一个类使用NicePCREMatch如下:
template<class Match_t>
vector<Match_t> NicePCRE<Match_t>::match(const string& buf)
{
[snip]
Match_t m;
[snip]
m.addGroup(std::string((const char *)tabptr + 2, name_entry_size - 3), \
buf.substr(ovector[2*n], ovector[2*n+1] - ovector[2*n]));
[snip]
addMatch(m);
[snip]
return _matches;
}
其中,
template<class Match_t>
void NicePCRE<Match_t>::addMatch(const Match_t& m)
{
_matches.push_back(m);
}
最后,客户端代码使用NicePCRE类,如下所示:
void test_NicePCRE_email_match(void)
{
NicePCRE<> npcre;
npcre.compile("(?P<username>[a-zA-Z]+?)(?:%40|@)(?P<domain>[a-zA-Z]+\.[a-zA-Z]{2,6})");
vector<NicePCREMatch> matches = npcre.match("toto@yahoo.com");
assert(!matches.empty());
assert(!strcmp(matches.begin()->group("username").c_str(), "toto"));
cout << matches.begin()->group("domain").c_str() << endl;
assert(!strcmp(matches.begin()->group("domain").c_str(), "yahoo.com"));
}
顺便说一下,这 - 几乎是 - 我的主要(有史以来最奇怪的TDD :)):
int main()
{
int test_cnt = 0;
cout << "Running test #" << test_cnt << " .." << endl;
test_NicePCRE_email_match();
cout << "OK." << endl << endl;
test_cnt++;
SleepEx(5000, 1);
return 0;
}
我在这里做错了什么?
修改 以下修改(与上面的版本比较)解决了我的问题。即,
void NicePCREMatch::addGroup(const string& group_name, const string& value)
{
_match.insert(pair<string, string>(group_name.c_str(), value.c_str()));
}
客户端代码(稍加修改)现在看起来像这样:
void test_NicePCRE_email_match(void)
{
NicePCRE<> npcre;
npcre.compile("(?P<username>[a-zA-Z]+?)(?:%40|@)(?P<domain>[a-zA-Z]+\.[a-zA-Z]{2,6})");
vector<NicePCREMatch> matches = npcre.match("toto@yahoo.com");
assert(!matches.empty());
try
{
assert(!strcmp(matches.begin()->group("username").c_str(), "toto"));
assert(!strcmp(matches.begin()->group("domain").c_str(), "yahoo.com"));
cout << "username = " << matches.begin()->group("username") << endl;
cout << "domain = " << matches.begin()->group("domain") << endl;
}
catch (const runtime_error& e)
{
cout << "Caught: " << e.what() << endl;
assert(0x0);
}
}
这很奇怪。有人可以解释一下。但是,我认为我的问题已经解决了。
谢谢大家。
答案 0 :(得分:0)
这可能是由三件事引起的 - 要么在执行find之后以某种方式修改映射,要么在程序中某处存在内存损坏,或者调试器根本没有显示迭代器的正确值。
尝试使用调试输出 - 如果在尝试输出值时代码崩溃,那么迭代器可能真的坏了。
另外,请确保在执行find后不修改地图。如果这样做,这可能会使迭代器无效,因此您需要在使用迭代器之前立即移动find调用。
如果上述两个选项都无法帮助您,可能会在某处出现内存损坏,您需要找到它。也许可以使用valgrind。请注意,只有当证明其他两个选项不可能时,这应该是你的最后手段。
答案 1 :(得分:0)
您的问题在这里
if (i == _match.end())
{
throw runtime_error("runtime_error: no such group");
}
return i->second;
你的发现由于某种原因失败了。我不能说为什么,因为我没有完整的代码。但是,在失败之后,你正在抛出一个错误,但是没有人可以赶到外面。请在调用方法组()的位置添加try catch,并在未找到匹配时实现逻辑。 我尝试使用你的示例代码片段(+一些更改来编译这些东西),看起来visual studio继续使用函数中的下一行,即使在throw语句之后也是如此。我不知道背后的理论。看到这样的行为,我有点意外。
[为了确保您的类结构不会导致问题,我尝试使用简单的全局方法,甚至该方法也给了我相同的行为。如果有人可以解释这个,请随意。]