2013-08-22 62 views
3

我写了一个std :: map的比较函数,所以我可以有自定义的键类型。std :: map比较函数和NULL

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

显示你在哪里添加元素。 – imreal

+1

你能发表一些关于你如何使用它的代码,和/或你如何向地图添加元素?我可以尝试重现这个问题。我没有看到任何与该代码有关的明显问题,因此在实现中可能会有些奇怪。 –

+0

如果你的GGString进入'NULL',它将插入你正在寻找的'NULL' *键*,而不是'NULL' *值* –

回答

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。因此,当在theKeymap的任何元素上调用比较器时,您将取消引用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); 
} 

希望这有助于!

+0

添加该代码不能解决问题,仍然在同一个地方崩溃。 –

+1

你可以发布堆栈跟踪吗?错误发生在哪里? – templatetypedef

+0

添加了堆栈跟踪。 –

0

不知该键比较功能应加以修订,以这样的事:

bool operator()(const GGString *&lhs, const GGString *&rhs) 
{ 
    if (lhs == NULL || rhs == NULL) 
    { 
     return false; 
    } 
    return strcmp(lhs->str(), rhs->str()) < 0; 
} 

基本上我想的参数应该是const的引用,也该函数应防止取消引用空指针

+0

它使比较较慢,可能会治愈症状。 – ypnos

+1

支持'null'可能是一个好主意,但是这个函数并没有给出严格的弱排序。对于任何值'a','comp(a,null)'和'comp(null,a)'都是假的,这意味着所有的值都等于'null',因此所有的值都是相等的。 –

+0

而是,执行此操作:'if(rhs == NULL)return false;如果(lhs == NULL)返回true;' –

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 
+0

是的,它是一个NULL指针,而不是垃圾指针。 –