读书人

multi地图的erase出错?(C++ Primer

发布时间: 2012-09-27 11:11:17 作者: rapoo

multimap的erase出错?(C++ Primer 习题10.26)
C++ Primer 习题10.26

编写程序建立作者及其作品的multimap容器,使用find函数在multimap中查找元素,并用erase删除,当要删除的元素不存在时,确保程序能正常工作。

一执行到erase就出错,看了参考,erase的用法没错啊!郁闷了!

Syntax:
#include <map>
void erase( iterator pos );
void erase( iterator start, iterator end );
size_type erase( const key_type& key );

[size=9px]

C/C++ code
#include <iostream>#include <map>#include <string>using namespace std;int main(){    multimap < string, string > authors;    authors.insert(make_pair("aa", "aaaaaaaaaaaaaaaa"));    authors.insert(make_pair("aa", "bbbbbbbbbbbbbbbb"));    authors.insert(make_pair("aa", "cccccccccccccccc"));    authors.insert(make_pair("pp", "000000000000000"));    authors.insert(make_pair("pp", "111111111111111"));    authors.insert(make_pair("pp", "222222222222222"));    authors.insert(make_pair("pp", "333333333333333"));    authors.insert(make_pair("pp", "444444444444444"));    authors.insert(make_pair("bb", "vvvvvvvvvvvvvvvv"));    authors.insert(make_pair("bb", "mmmmmmmmmmmmmmmm"));    authors.insert(make_pair("bb", "gggggggggggggggg"));    authors.insert(make_pair("bb", "yyyyyyyyyyyyyyyy"));    authors.insert(make_pair("aa", "dddddddddddddddd"));    authors.insert(make_pair("aa", "****************"));    authors.insert(make_pair("aa", "////////////////"));    //-------------------------------------------------    multimap < string, string > ::iterator it;    for (it = authors.begin(); it != authors.end(); ++it)        cout << it->first << "\t" << it->second << endl;    //--------------------------------------------------    cout << "enter element name which you want to erase: ";    string elementNameForDelete;    cin >> elementNameForDelete;    if (cin && !elementNameForDelete.empty())    {        typedef multimap < string, string > ::size_type sz_type;        sz_type counts = authors.count(elementNameForDelete);        it = authors.find(elementNameForDelete);        cout << "\nFound: " << counts << "\t" << elementNameForDelete << endl;        for (sz_type cnt = 0; cnt != counts; ++cnt, ++it)        {            if (it != authors.end())                authors.erase(it);//执行到这里就出错            //cout << it->first <<"\t"<< it->second << endl;        }    }    //---------------------------------------------------    cout << "\nnow elements list: " << endl;    it = authors.begin();    for (; it != authors.end(); ++it)        cout << it->first << "\t" << it->second << endl;    return 0;}
[/size]

[解决办法]
it != authors.end() 是不是越界了
[解决办法]
C/C++ code
#include <iostream>#include <map>#include <string>using namespace std;int main(){    multimap < string, string > authors;    authors.insert(make_pair("aa", "aaaaaaaaaaaaaaaa"));    authors.insert(make_pair("aa", "bbbbbbbbbbbbbbbb"));    authors.insert(make_pair("aa", "cccccccccccccccc"));    authors.insert(make_pair("pp", "000000000000000"));    authors.insert(make_pair("pp", "111111111111111"));    authors.insert(make_pair("pp", "222222222222222"));    authors.insert(make_pair("pp", "333333333333333"));    authors.insert(make_pair("pp", "444444444444444"));    authors.insert(make_pair("bb", "vvvvvvvvvvvvvvvv"));    authors.insert(make_pair("bb", "mmmmmmmmmmmmmmmm"));    authors.insert(make_pair("bb", "gggggggggggggggg"));    authors.insert(make_pair("bb", "yyyyyyyyyyyyyyyy"));    authors.insert(make_pair("aa", "dddddddddddddddd"));    authors.insert(make_pair("aa", "****************"));    authors.insert(make_pair("aa", "////////////////"));    //-------------------------------------------------    multimap < string, string > ::iterator it;    for (it = authors.begin(); it != authors.end(); ++it)        cout << it->first << "\t" << it->second << endl;    //--------------------------------------------------    cout << "enter element name which you want to erase: ";    string elementNameForDelete;    cin >> elementNameForDelete;    if (cin && !elementNameForDelete.empty())    {        typedef multimap < string, string > ::size_type sz_type;        sz_type counts = authors.count(elementNameForDelete);        it = authors.find(elementNameForDelete);        cout << "\nFound: " << counts << "\t" << elementNameForDelete << endl;        //----------------------------------------------        multimap < string, string > ::iterator end=it;        while(counts--)            end++;        authors.erase(it,end);        //----------------------------------------------   //     for (sz_type cnt = 0; cnt != counts; ++cnt, ++it)   //     {   //         if (it != authors.end())            //{   //             authors.erase(it);//执行到这里就出错            //}   //         //cout << it->first <<"\t"<< it->second << endl;   //     }    }    //---------------------------------------------------    cout << "\nnow elements list: " << endl;    it = authors.begin();    for (; it != authors.end(); ++it)        cout << it->first << "\t" << it->second << endl;    return 0;} 


[解决办法]

C/C++ code
#include <iostream>#include <map>#include <string>using namespace std;int main(){    multimap < string, string > authors;    authors.insert(make_pair("aa", "aaaaaaaaaaaaaaaa"));    authors.insert(make_pair("aa", "bbbbbbbbbbbbbbbb"));    authors.insert(make_pair("aa", "cccccccccccccccc"));    authors.insert(make_pair("pp", "000000000000000"));    authors.insert(make_pair("pp", "111111111111111"));    authors.insert(make_pair("pp", "222222222222222"));    authors.insert(make_pair("pp", "333333333333333"));    authors.insert(make_pair("pp", "444444444444444"));    authors.insert(make_pair("bb", "vvvvvvvvvvvvvvvv"));    authors.insert(make_pair("bb", "mmmmmmmmmmmmmmmm"));    authors.insert(make_pair("bb", "gggggggggggggggg"));    authors.insert(make_pair("bb", "yyyyyyyyyyyyyyyy"));    authors.insert(make_pair("aa", "dddddddddddddddd"));    authors.insert(make_pair("aa", "****************"));    authors.insert(make_pair("aa", "////////////////"));    //-------------------------------------------------    multimap < string, string > ::iterator it;    for (it = authors.begin(); it != authors.end(); ++it)        cout << it->first << "\t" << it->second << endl;    //--------------------------------------------------    cout << "enter element name which you want to erase: ";    string elementNameForDelete;    cin >> elementNameForDelete;    authors.erase(elementNameForDelete);//删除拥有该键的所有元素    cout << "\nnow elements list: " << endl;    it = authors.begin();    for (; it != authors.end(); ++it)        cout << it->first << "\t" << it->second << endl;    return 0;}
[解决办法]
探讨
能告诉为什么吗?讲讲原因?为什么那句代码会出错?

[解决办法]
在我的环境下运行程序没有报错,但是逻辑已经不对了,运行结果是不对的;3,4楼的做法是正确的,7楼说得不是很准确,erase(it)之后确实是会把对应元素删掉,但是不是所有的。删掉了一个数据之后,迭代器所指示的数据已经不正确了。
我觉得出现什么结果,也是和编译器的不同而不同。
[解决办法]
这个是STL里面元素删除的一个很容易碰到的问题,循环中 itr ++, erase(itr) 之后也不管itr的事,继续使用。

所有的STL提供的类的erase(itr)之后,itr已经是一个无效的指示器了,再做itr ++ 操作就会有问题,
不过一般list,map,multimap 等 erase 都提供了返回值,返回删除元素后的下一个指示器。

一般不只接在for中写itr ++,如下写:
if( cond )
{
itr = yy.erase(itr);
}
else
{
itr ++;
}

或者 yy.erase(itr ++);
[解决办法]
很显然的迭代器实效的例子
C/C++ code
// 121.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>#include <map>#include <string>using namespace std;class AAA{public:    static void display1()    {        printf("display1 is called.\n");    }    void display2()    {        printf("display2 is called.\n");            }};typedef struct FILEINFO {     char Sum[100];     char Say[100]; }FileInfo ; int _tmain(int argc, _TCHAR* argv[]){    //// 静态函数指针pFun1    //void (*pFun1)() = &AAA::display1;    //pFun1(); // 输出display1 is called.    //// 非静态函数指针pFun2    //    //void (AAA::*pFun2)()= &AAA::display2; // 此行已编译期报错    //AAA::*pFun2(); // 我想此行输出display2 is called.    //AAA a;    //    ///*    //问题一:    //如何实现pFun2呢?    //*/    multimap < string, string > authors;    authors.insert(make_pair("aa", "aaaaaaaaaaaaaaaa"));    authors.insert(make_pair("aa", "bbbbbbbbbbbbbbbb"));    authors.insert(make_pair("aa", "cccccccccccccccc"));    authors.insert(make_pair("pp", "000000000000000"));    authors.insert(make_pair("pp", "111111111111111"));    authors.insert(make_pair("pp", "222222222222222"));    authors.insert(make_pair("pp", "333333333333333"));    authors.insert(make_pair("pp", "444444444444444"));    authors.insert(make_pair("bb", "vvvvvvvvvvvvvvvv"));    authors.insert(make_pair("bb", "mmmmmmmmmmmmmmmm"));    authors.insert(make_pair("bb", "gggggggggggggggg"));    authors.insert(make_pair("bb", "yyyyyyyyyyyyyyyy"));    authors.insert(make_pair("aa", "dddddddddddddddd"));    authors.insert(make_pair("aa", "****************"));    authors.insert(make_pair("aa", "////////////////"));    //-------------------------------------------------    multimap < string, string > ::iterator it;    for (it = authors.begin(); it != authors.end(); ++it)        cout << it->first << "\t" << it->second << endl;    //--------------------------------------------------    cout << "enter element name which you want to erase: ";    string elementNameForDelete;    cin >> elementNameForDelete;    if (cin && !elementNameForDelete.empty())    {        typedef multimap < string, string > ::size_type sz_type;        sz_type counts = authors.count(elementNameForDelete);        it = authors.find(elementNameForDelete);        cout << "\nFound: " << counts << "\t" << elementNameForDelete << endl;        for (sz_type cnt = 0; cnt != counts; ++cnt, ++it)        {            if (it != authors.end())                    it=authors.erase(it);//重新获取迭代器                 it-- ;//迭代器回指一步和下次循环的it++抵消,因为  it=authors.erase(it) 一句it获得的是刚刚删除位置的下一位也就是下一个要删除的位置,所以要回指,但这里依然后有遗漏//就是没处理删除的是begin位置的情况,若删除begin回指后超出begin位置会非法,楼主自己再小小的处理下,但是改完之后现在程序除了删除aa都没问题可以测试一下              //cout << it->first <<"\t"<< it->second << endl;        }    }    //---------------------------------------------------    cout << "\nnow elements list: " << endl;    it = authors.begin();    for (; it != authors.end(); ++it)        cout << it->first << "\t" << it->second << endl;    return 0;} 

读书人网 >C++

热点推荐