2

重複の可能性:
erase()を呼び出した後のstd :: map::iteratorの問題

私が現在抱えている問題について、あなたが私に教えてくれるかもしれません。したがって、問題は、マップ内のいくつかの要素を消去しようとすると、アクセスメモリが不良になることです。次のtypedefを想定しています:

typedef std::map < std::string *, Document *, pStringCompare > Map;

そして、次のすべてのコードを実行する前に、(たとえば)2つの要素を含むマップをすでにインスタンス化したと仮定します。このコードはうまく機能しています:

Map::iterator it = documents.begin();

std::string *s = it->first;
Document *d = it->second;

documents.erase(it);

delete d;
delete s;

しかし、イテレータでループしようとすると、エラーが発生します。

for (Map::iterator it = documents.begin() ; it != documents.end() ; it++)
{
    std::string s = * ( it->first);
    Document dd = * (it->second);
    std::cout << s << " || " << dd;
    documents.erase(it);  // This line causes the bad access memory error.
}

ご協力いただきありがとうございます !本当にありがたいです!

アレクス

4

2 に答える 2

6

無効化されたイテレータにアクセスしています。一度渡すと無効になるため、ループ内erase()でインクリメントすることはできません。for詳細については、イテレータ無効化ルールを参照してください。

無効化されたイテレータにアクセスしないように、ループは次のように構成する必要があります。

for (Map::iterator it = documents.begin() ; it != documents.end() ; )
{
    std::string s = * ( it->first);
    Document dd = * (it->second);
    std::cout << s << " || " << dd;
    documents.erase(it++);
}

もっとドキュメントを読んで、ここで何が起こっているのかを理解することを強くお勧めします。たとえば、これを参照してください。

幸運を!

于 2012-11-09T19:11:28.040 に答える
1

または:

while ((Map::iterator iter = documents.begin()) != documents.end())
{
   std::string s = * ( iter->first);
   Document dd = * (iter->second);
   std::cout << s << " || " << dd;
   documents.erase(iter);
}
于 2012-11-09T19:27:32.257 に答える