Key的小于操作符号重载不正确导致map占用CPU占用100%的分析
2007-04-01 23:26
465 查看
一、问题描述。
map的key的小于操作符重载的实现不正确,导致在删除一个元素时候,CPU占用100%。
有问题的代码如下:
using namespace std;
class CUser
...{
public:
CUser(int iID,int iKey):miID(iID),miKey(iKey)...{};
~CUser()...{};
public:
int miID;
int miKey;
//小于操作符号重载有问题的实现
bool operator<(const CUser &rhs) const
...{
if(miID < rhs.miID)
...{
return true;
}
if(miKey < rhs.miKey)
...{
return true;
}
return false;
};
//小于操作符号重载正确的实现
/**//*
bool operator<(const CUser &rhs) const
{
if(miID != rhs.miID)
{
return miID < rhs.miID;
}
return miKey < rhs.miKey;
};
*/
};
typedef map<CUser,string> CUserMap;
typedef CUserMap::iterator CUMIterator;
int main(int argc, char* argv[])
...{
CUserMap cu;
cu[CUser(1,3)] = "1--3";//Node A
cu[CUser(3,1)] = "3--1";//Node B
//该map的结构为Head(end),A,B
cu.erase(CUser(3,1));//此处程序挂在这儿,CPU占用100%
cout << "hello"<<endl;
return 0;
}
二、原因分析
1、 这是插入A、B节点后map cu的树结构
2、 STL源码分析
[align=left](1)map的删除函数[/align]
size_type erase(const key_type& _Keyval)// _Keyval为B(3,1)
...{ // erase and count all that match _Keyval
// equal_range返回_Keyval可以插入的第一个位置和最后一个位置
//[_Where.first, _Where.second),也就是元素=_Keyval的元素区间,
//此处正确的结果应该是[B,Head(end))
//但此次结果却为[B,A),导致执行_Distance时候,出现死循环
_Pairii _Where = equal_range(_Keyval);
size_type _Num = 0;
//_Distance计算_Where.second到_Where.first的距离,
//是通过++计算的
_Distance(_Where.first, _Where.second, _Num);
erase(_Where.first, _Where.second);
return (_Num);
}
[align=left](2)[/align]
template<class _BidIt,
class _Diff> inline
void _Distance2(_BidIt _First, _BidIt _Last, _Diff& _Off,
bidirectional_iterator_tag)
...{ // add to _Off distance between bidirectional iterators (redundant)
// B++ == Head, Head ++ == Head
for (; _First != _Last; ++_First)
++_Off;
}
[align=left] (3)获取_Where.second的结果[/align]
_Nodeptr _Ubound(const key_type& _Keyval) const
...{ // find leftmost node greater than _Keyval
_Nodeptr _Pnode = _Root();
_Nodeptr _Wherenode = _Myhead; // end() if search fails
// _Keyval= B(3,1), _Pnode = A(1,3)
while (!_Isnil(_Pnode))
//此处comp调用了Cuser的<,B(3,1) < A(1,3) 应该是false,但是这里却返回true
if (this->comp(_Keyval, _Key(_Pnode)))
...{ // _Pnode greater than _Keyval, remember it
_Wherenode = _Pnode;
_Pnode = _Left(_Pnode); // descend left subtree
}
else
_Pnode = _Right(_Pnode); // descend right subtree
return (_Wherenode); // return best remembered candidate
}
[align=left] [/align]
[align=left]3、 根本原因[/align]
[align=left]在插入的时候,首先插入的是A(1,3),在插入B时候,使用的比较操作是comp(A, B),但在删除的时候,用到是comp(B,A). [/align]
[align=left]comp(A, B) => A(1,3) < B(3,1) 结果为true[/align]
[align=left]comp(B, A) => B(3,1) < A(1,3) 结果为true[/align]
[align=left]comp(A, B) == !( comp(B, A)),[/align]
[align=left]即Cuser的< 不符合小于的定义[/align]
三、对策
[align=left]1、在重载操作符时候,要使用其基本语意进行验证,看是否自相矛盾,例如在定义<时候,可以判断(A<B) != (B<A)是否为真。[/align]
[align=left]2、操作符<的定义一般都是类似如下定义[/align]
bool operator<(const CUser &rhs) const
...{
if(miID != rhs.miID)
...{
return miID < rhs.miID;
}
return miKey < rhs.miKey;
};
[align=left] [/align]
相关文章推荐
- HashMap-死锁导致cpu占用100%分析
- [原]分析Vista导致资源管理器占用CPU资源100%的问题的原因及解决办法
- HashMap-死锁导致cpu占用100%分析(转)
- Tomcat CPU占用100%异常分析与处理
- linux中nohup写操作与程序中读操作冲突引起cpu占用100%
- 服务器php-cgi.exe进程过多,导致CPU占用100%的解决方法
- win7下CPU资源占用100%的原因分析及对策
- 一例由于一网站cpu占用过高导致服务器cpu占用始终是100%的问题解决
- CSC.exe经常出来占用CPU资源,导致CPU100%
- Symbian开发时,模拟器经常导致CPU占用100%?
- 服务器大量php-cgi.exe进程,导致CPU占用100%的解决
- jstack分析cpu占用100%
- openstack kvm WINDOWS虚拟机VDAGENT导致CPU占用100%问题的解决
- DBA案例分析:如何解决CPU占用100%的问题
- Linux jstack分析cpu占用100%
- 导致eclipse在空闲时CPU一直占用100%或50%的原因及解决
- cisvc.exe导致CPU占用100%的解决方法。
- windows更新Microsoft Update导致svchost.exe占用CPU 100%完美解决方法
- 导致eclipse在空闲时CPU一直占用100%或50%的原因及解决
- jstack分析cpu占用100%(转)