C++中STL常见问题汇总,越来越熟悉STL底层原理和应用(2)
liebian365 2024-10-25 15:40 20 浏览 0 评论
STL中迭代器什么时候会失效?
- 对于序列容器vector,deque来说,使用erase后,后边的每个元素的迭代器都会失效,后边每个元素都往前移动一位,erase返回下一个有效的迭代器。
说明
当删除一个元素后,内存中的数据会发生移动以保证数据的紧凑。所以删除一个元素后,其他数据的地址发生了变化,之前获取的迭代器根据原有信息就访问不到正确的数据。
//迭代器失效
void vectorTest()
{
vector<int> container;
for (int i = 0; i < 10; i++)
{
container.push_back(i);
}
vector<int>::iterator iter;
for (iter = container.begin(); iter != container.end(); iter++)
{
if (*iter > 3)
container.erase(iter);
}
for (iter = container.begin(); iter != container.end(); iter++)
{
cout<<*iter<<endl;
}
}
//代码修改,ok
void vectorTest()
{
vector<int> container;
for (int i = 0; i < 10; i++)
{
container.push_back(i);
}
vector<int>::iterator iter;
for (iter = container.begin(); iter != container.end();)
{
if (*iter > 3) {
iter = container.erase(iter);
}
else {
iter ++;
}
}
for (iter = container.begin(); iter != container.end(); iter++)
{
cout<<*iter<<endl;
}
}
- 对于关联容器map,set来说,使用了erase后,当前元素的迭代器失效,但是其结构是红黑树,删除当前元素,不会影响下一个元素的迭代器,所以在调用erase之前,记录下一个元素的迭代器即可。
说明:
虽然删除了一个元素,整棵树也会调整,以符合红黑树规范,但是单个节点在内存中的地址没有变化,变化的是各节点之间的指向关系。删除一个结点不会对其他结点造成影响。 erase迭代器只是被删元素的迭代器失效。
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main()
{
map<string, int> mapData;
mapData["a"] = 1;
mapData["b"] = 2;
mapData["c"] = 3;
map<string, int>::iterator itMap = mapData.begin();
while (itMap != mapData.end())
{
if (strcmp(itMap->first.c_str(), "a") == 0)
{
mapData.erase(itMap++);
}
else
{
itMap++;
}
/* 迭代器失效
if (strcmp(itMap->first.c_str(), "a") == 0)
{
mapData.erase(itMap);
}
itMap++;
*/
}
}
- list来说,它使用了不连续分配的内存,并且它的erase方法也会返回下一个有效的迭代器
上面两种方法都可以使用。
STL中迭代器的作用,有指针为何还要迭代器?
- 迭代器作用
(1)用于指向顺序容器和关联容器中的元素。
(2)通过迭代器可以读取它指向的元素。
(3)通过非const迭代器可以修改其指向的元素。
- 迭代器和指针的区别
迭代器不是指针,是类模板,表现得像指针。迭代器模拟了指针的一些功能,重载了指针的一些操作符。迭代器本质是封装了原生指针,是指针概念的一种提升,提供了比指针更高级的行为,可以看成一种智能指针,他可以根据不同类型的数据结构来实现不同的++,--等操作。
- 迭代器产生的原因
Iterator类的访问方式就是把不同集合类的访问逻辑抽象出来,使得不用暴露集合内部的结构而达到循环遍历集合的效果。
STL 迭代器是怎么删除元素的
这主要考察迭代器失效的问题,上面已经总结。
STL 中 resize 和 reserve 的区别
- 两个概念
(1)capacity:该值在容器初始化时赋值,指的是容器能够容纳的最大的元素的个数。还不能通过下标等访问,因为此时容器中还没有创建任何对象。
(2)size:指的是此时容器中实际的元素个数。可以通过下标访问0-(size-1)范围内的对象。
- resize和reserve区别
(1)resize既分配了空间,也创建了对象;reserve表示容器预留空间,但并不是真正的创建对象,需要通过insert()或push_back()等创建对象。
(2)resize既修改capacity大小,也修改size大小;reserve只修改capacity大小,不修改size大小
(3)两者的形参个数不一样。 resize带两个参数,一个表示容器大小,一个表示初始值(默认为0);reserve只带一个参数,表示容器预留的大小。
STL 容器动态链接可能产生的问题?
- 可能会产生什么问题
容器是一种动态分配内存空间的一个集合类型的变量。在一般的程序函数里,局部容器,参数传递容器,参数传递容器的引用,参数传递容器指针都是可以正常运行的,而在动态链接库函数内部使用容器也是没有问题的,但是给动态库函数传递容器的对象本身,则会出现内存堆栈破坏的问题。
- 产生问题原因
容器和动态链接库相互支持不够好,动态链接库函数中使用容器时,参数中只能传递容器的引用,并且要保证容器的大小不能超出初始大小,否则导致容器自动重新分配,就会出现内存堆栈破坏问题
map 和 unordered_map 的区别?底层实现
- map实现机理
map内部实现了一个红黑树,红黑树有自动排序的功能,因此map内部所有元素都是有序的,红黑树的每一个节点都代表着map的一个元素。对于map进行的查找、删除、添加等一系列的操作都相当于是对红黑树进行的操作。map中的元素是按照二叉查找树存储的(左子树上所有节点的键值都小于根节点的键值,右子树所有节点的键值都大于根节点的键值)。中序遍历可将键值按照从小到大遍历出来。
- unordered_map实现机理
unordered_map内部实现了一个哈希表,通过把关键码值映射到Hash表中一个位置来访问记录,查找时间复杂度可达O(1),在海量数据处理中有着广泛应用。因此,元素的排列顺序是无序的。
push_back 和 emplace_back 的区别
要将一个临时变量push到容器的末尾,push_back()需要先构造临时对象,再将这个对象拷贝到容器的末尾,而emplace_back()则直接在容器的末尾构造对象,这样就省去了拷贝的过程。
#include<iostream>
using namespace std;
#include<string>
#include<vector>
class TestA
{
public:
string str;
TestA(int i)
{
str = to_string(i);
cout << "构造函数的调用" << endl;
}
~TestA()
{
//cout << "析构函数的调用" << endl;
}
TestA(const TestA& other) :str(other.str)
{
cout << "拷贝函数构造" << endl;
}
};
int main()
{
vector< TestA> vec;
vec.reserve(10);
for (int i = 0; i < 10; i++)
{
//调用了10次构造函数和10次拷贝构造函数
vec.push_back(i);
//调用了10次构造函数,没有调用拷贝构造函数
//vec.emplace_back(i);
}
return 0;
}
push_back()运行结果:
emplece_back()运行结果:
相关推荐
- 4万多吨豪华游轮遇险 竟是因为这个原因……
-
(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...
- “菜鸟黑客”必用兵器之“渗透测试篇二”
-
"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...
- 科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白
-
作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...
- 麦子陪你做作业(二):KEGG通路数据库的正确打开姿势
-
作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...
- 知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势
-
智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...
- 每日新闻播报(September 14)_每日新闻播报英文
-
AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...
- 香港新巴城巴开放实时到站数据 供科技界研发使用
-
中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...
- 5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper
-
本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...
- Qt动画效果展示_qt显示图片
-
今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...
- 如何从0到1设计实现一门自己的脚本语言
-
作者:dong...
- 三年级语文上册 仿写句子 需要的直接下载打印吧
-
描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...
- C++|那些一看就很简洁、优雅、经典的小代码段
-
目录0等概率随机洗牌:1大小写转换2字符串复制...
- 二年级上册语文必考句子仿写,家长打印,孩子照着练
-
二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)