容器使用迭代器时,不要改变容器的大小
/在操作迭代器的过程中(使用了迭代器这种循环体),千万不要改变vectori容器的容量,也就是不要增加或者删除vectori容器中的元素
/往容器中增加或者从容器中删除元素,这些操作可能会使指向容器元素的指针、引用、迭代器失效。
失效就表示不能再代表任何容器中的元素。一旦使用失效的东西,就等于犯了严重的程序错误,很多情况下,程序会直接崩溃。
原迭代器指的是进行操作之前保存的迭代器,包括begin()、end()以及其他位置的迭代器。
成员函数push_back():会在容器末尾添加一个元素。如果容器有剩余空间(capacity() > size()),则直接添加新元素到容器尾部。此时,原迭代器中end()会失效,其他的都不会失效。否则,会导致容器重新分配内存,然后将数据从原内存复制到新内存,再在尾部添加新元素。此时,由于内存重新分配,原迭代器(所有)都失效。
成员函数pop_back():直接将容器中的最后一个元素删除,原迭代器中end()会失效,其余的都不会失效。
成员函数insert(iterator, n):如果容器有剩余空间,先在容器尾部插入一个元素,然后将插入点及之后的元素都向后移动一位,然后在插入点创建新元素。否则,会导致容器重新分配内存,接着将插入点之前的元素复制过去,在插入点创建新元素,再将插入点之后的元素复制过去。因此,如果没有内存的重新分配,原迭代器中插入点及插入点之后的迭代器(包括end())都失效。如果有内存的重新分配,原迭代器(所有)都失效。
成员函数erase(iterator):将删除点及之后的元素都向前移动一位,然后删除最后一个元素。因此,原迭代器中删除点之前的迭代器都有效,插入点及插入点之后的迭代器都失效。
成员函数push_back():会直接在容器末尾添加一个元素。原迭代器中end()会失效,其他的都不会失效。
成员函数push_front():会直接在容器头部添加一个元素。原迭代器中begin()会失效,其他的都不会失效。
成员函数pop_back():会直接删除最后一个元素。原迭代器中end()会失效,其他的都不会失效
成员函数pop_front():会直接在容器头部删除一个元素。原迭代器中begin()会失效,其他的都不会失效。
成员函数insert(iterator, n):如果插入点之前的元素较少,会在容器头部插入一个元素,然后将插入点及其之前的所有元素向前移动一位,再在插入点创建新元素。否则,将插入点及其之后的元素向后移动一位,再在插入点创建新元素。因此,向前移动则导致原迭代器中插入点及插入点之前的迭代器都失效;向后移动则导致迭代器中插入点及插入点之后的迭代器都失效。
成员函数erase(iterator):如果删除点之前的元素较少,将删除点之前的所有元素向后移动一位,再删除第一个元素。否则,将删除点之后的所有元素向前移动一位,再删除最后一个元素。因此,向前移动将导致原迭代器中删除点及删除点之后的迭代器失效;向后移动将导致原迭代器中删除点及删除点之前的迭代器都失效。
因为list的底层结构是双向链表,所有操作都只是针对节点移动指针,不会涉及到位置变化,操作影响的范围很小。
成员函数push_back():原迭代器中end()会失效,其他的都不会失效。
成员函数push_front():原迭代器中begin()会失效,其他的都不会失效。
成员函数pop_back():原迭代器中end()会失效,其他的都不会失效
成员函数pop_front():原迭代器中begin()会失效,其他的都不会失效。
成员函数insert(iterator, n):原迭代器中插入点会失效,其他的都不会失效。
成员函数erase(iterator):原迭代器中删除点会失效,其他的都不会失效。
关联容器的底层结构为红黑树,所有操作同list一样,都只是移动指针,各成员函数导致的迭代器失效问题同list。
vector v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);vector::iterator it = find(v1.begin(), v1.end(), 2);if (it != v1.end()){it=v1.insert(it, 20);//及时更新了it指向的位置}
序列性容器::(vector和list和deque)
erase迭代器不仅使所指向被删元素的迭代器失效,而且使被删元素之后的所有迭代器失效,所以不能使用erase(iter++)的方式,但是erase的返回值为下一个有效的迭代器。
所以正确方法为::for( iter = c.begin(); iter != c.end(); )iter = c.erase(iter);
关联性容器::(map和set比较常用)
erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器,
所以正确方法为::
for( iter = c.begin(); iter != c.end(); )
c.erase(iter++);
Tips:
其实对于list两种方式都可以正常工作
如果要在Vector容器中存放结构体类型的变量,经常见到两种存放方式.
方式一:放入这个结构体类型变量的副本。
方式二:放入指向这个结构体类型变量的指针。
假设结构体类型变量是这样的,
typedef struct student{char school_name[100];char gender;int age;bool is_absent;
} StudentInfo;
那么,方式一和方式二的实现分别如下所示:
/*[方式一] 结构体放栈中,vector中放副本---------------------*/
#include
#include
#include
typedef struct student{char school_name[100];char gender;int age;bool is_absent;
} StudentInfo;typedefstd::vector StudentInfoVec;void print(StudentInfoVec* stduentinfovec){for (int j=0;j<(*stduentinfovec).size();j++){std::cout<<(*stduentinfovec)[j].school_name<<"\t"<<(*stduentinfovec)[j].gender<<"\t"<<(*stduentinfovec)[j].age<<"\t"<<(*stduentinfovec)[j].is_absent<<"\t"<StudentInfo micheal={"Micheal",'m',18,false};StudentInfo cherry={"Cherry",'f',16,true};StudentInfoVec studentinfovec;studentinfovec.push_back(micheal);studentinfovec.push_back(cherry);print(&studentinfovec);return 0;
}

/*[方式二] 结构体放入堆中,vector中放指针---------------------*/
typedef struct student{char* school_name;char gender;int age;bool is_absent;
} StudentInfo;typedefstd::vector StudentInfoPtrVec;void print(StudentInfoPtrVec*stduentinfoptrvec){for (int j=0;j<(*stduentinfoptrvec).size();j++){std::cout<<(*stduentinfoptrvec)[j]->school_name<<"\t"<<(*stduentinfoptrvec)[j]->gender<<"\t"<<(*stduentinfoptrvec)[j]->age<<"\t"<<(*stduentinfoptrvec)[j]->is_absent<<"\t"<StudentInfoPtrVec studentinfoptrvec;char* p_char_1=NULL;p_char_1=new char[100];strcpy(p_char_1,"Micheal");StudentInfo* p_student_1=new StudentInfo;p_student_1->school_name=p_char_1;p_student_1->gender='m';p_student_1->age=18;p_student_1->is_absent=false;studentinfoptrvec.push_back(p_student_1);char* p_char_2=NULL;p_char_2=new char[100];strcpy(p_char_2,"Cherry");StudentInfo* p_student_2=new StudentInfo;p_student_2->school_name=p_char_2;p_student_2->gender='f';p_student_2->age=16;p_student_2->is_absent=false;studentinfoptrvec.push_back(p_student_2);print(&studentinfoptrvec);delete p_char_1;delete p_student_1;delete p_char_2;delete p_student_2;return 0;/*也可以这样释放内存*///我们要释放内存,自己new的就要自己释放,否则会造成内存泄漏;
std:vectoriterator pos:
for(pos =studentinfoptrvec.begin(:pos !=studentinfoptrvec.end();++pos)
delete(*pos);
}
p_student_2;
return 0;
/*也可以这样释放内存*///我们要释放内存,自己new的就要自己释放,否则会造成内存泄漏;
std:vector
for(pos =studentinfoptrvec.begin(:pos !=studentinfoptrvec.end();++pos)
delete(*pos);
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t0GfGth7-1668872304536)(https://raw.githubusercontent.com/Ding-yixia/Typora/master/image-20221117232144015.png)]