3

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 になるのを防ぐことはできますが、何かがおかしいようで、問題ではなく症状を治したくありません。

ありがとう

4

3 に答える 3

5

このコードでは:

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かどうかをチェックしていませんNULLtheKeyしたがって、および の任意の要素でコンパレータが呼び出されると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);
}

お役に立てれば!

于 2013-08-22T21:41:43.373 に答える
0

NULL にアクセスするとクラッシュが発生しますか? ポインターをマップに格納しています。マップに保存した後、ポインターの1つを削除した可能性はありますか? このようなもの:

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
于 2013-08-22T23:20:36.243 に答える
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 ポインターの逆参照から保護する必要があると考えています

于 2013-08-22T22:29:29.470 に答える