我为std :: map编写了一个比较函数,因此我可以使用自定义键类型。
std::map<GGString *, GGObject *, GGDictionaryMapCompare> _map;
...
class GGDictionaryMapCompare
{
public:
bool operator()(GGString * lhs, GGString * rhs)
{
return strcmp(lhs->str(), rhs->str()) < 0;
}
};
添加元素的代码:
GGObject *GGDictionary::addKeyObject(GGString *theKey, GGObject *theObject)
{
if (theKey == NULL || theObject == NULL)
return NULL;
_map.insert(std::pair<GGString *, GGObject *>(theKey, theObject));
return theObject;
}
导致崩溃的代码:
GGObject *GGDictionary::objectForKey(GGString *theKey)
{
if (theKey == NULL)
return NULL;
std::map<GGString *, GGObject *, GGDictionaryMapCompare>::iterator ii = _map.find(theKey);
if (ii == _map.end())
return NULL;
return GGAutoRelease(ii->second);
}
堆栈追踪:
#0 0x00009f15 in GGString::str()
#1 0x0004a4c4 in GGDictionaryMapCompare::operator()(GGString*, GGString*)
#2 0x0004a3d3 in std::_Rb_tree<GGString*, std::pair<GGString* const, GGObject*>, std::_Select1st<std::pair<GGString* const, GGObject*> >, GGDictionaryMapCompare, std::allocator<std::pair<GGString* const, GGObject*> > >::find(GGString* const&)
#3 0x00049b04 in std::map<GGString*, GGObject*, GGDictionaryMapCompare, std::allocator<std::pair<GGString* const, GGObject*> > >::find(GGString* const&)
#4 0x00048ec9 in GGDictionary::objectForKey(GGString*)
问题是lhs是NULL。我从不在地图中插入NULL,因此不应该发生这种情况。知道为什么吗?或者我只是做比较功能错了?我可以防止得到NULL,但似乎有些问题,我不想治愈症状而不是问题。
由于
答案 0 :(得分:4)
在此代码中:
GGObject *GGDictionary::objectForKey(GGString *theKey)
{
std::map<GGString *, GGObject *, GGDictionaryMapCompare>::iterator ii = _map.find(theKey);
if (ii == _map.end())
return NULL;
return GGAutoRelease(ii->second);
}
您没有检查theKey
是否为NULL
。因此,当在theKey
和map
的任何元素上调用比较器时,您将取消引用NULL
。
要解决此问题,请尝试添加NULL
支票:
GGObject *GGDictionary::objectForKey(GGString *theKey)
{
if (theKey == NULL) return NULL;
std::map<GGString *, GGObject *, GGDictionaryMapCompare>::iterator ii = _map.find(theKey);
if (ii == _map.end())
return NULL;
return GGAutoRelease(ii->second);
}
希望这有帮助!
答案 1 :(得分:0)
我想知道密钥比较功能是否应修改为:
bool operator()(const GGString *&lhs, const GGString *&rhs)
{
if (lhs == NULL || rhs == NULL)
{
return false;
}
return strcmp(lhs->str(), rhs->str()) < 0;
}
基本上我认为参数应该是const引用,而且函数应该防止取消引用NULL指针
答案 2 :(得分:0)
您确定访问NULL时发生崩溃吗?您正在地图中存储指针;是否有可能在将其存储到地图后删除了其中一个指针?像这样:
dict->addKeyObject( key1, obj1 );
delete key1; // now dict has a pointer to deleted key1
dict->addKeyObject( key2, obj2 ); // now dict will compare key2 to key1, causing crash