swap 会导致string迭代器失效的疑惑

2022.4.8

标准库函数swap可以交换顺序容器元素,

对于vector,交换实际上并没有进行内存的复制,只是交换了两个vector的begin指针,所以不会导致原本的迭代器失效,但是原本指向v1的迭代器在交换后指向了v2,

对于string,string的基本实现有2种,

一,一个指向字符串begin的指针+一个表示字符串长度的整形+一个当前string已分配空间大小的整形

二,三个指针,分别指向,字符串begin,字符串end,当前已分配空间end

实测代码发现,swap并没有交换string的begin指针,而是进行了内存的交换,

为啥呢

2022.4.8

string在标准里有 短字符串优化(Short String Optimization,简称SSO)的做法

小于一定字符长度的string会直接储存在栈上而不是堆中,为了减少访问开销, 这个长度具体取决于实现,msvc的默认长度是15

而如果s1有优化指向栈,s2无优化指向堆,交换元素的时候,考虑到交换结果,s1要重新定位到堆上,所以此时s1会销毁之前栈上的空间,此举显然会导致之前s1的迭代器失效,

而对于s2,重新定位到栈上,就得重新在栈上开辟空间,但之前堆上的空间会被s1利用,不会销毁,

如下图所示,swap过后,s2一开始指向的堆空间依然存在,s1一开始的栈空间被释放,所以s2的迭代器依然有效,能够访问,此时访问s1迭代器会运行错误,提示迭代器失效

 

 

 

 

实测都在堆上的string交换不会导致迭代器失效,这显然合理,此时的交换仅仅同vector的交换操作,仅仅是交换begin指针

都在栈上的string交换会导致所有迭代器失效,这点我认为是默认情况下,栈上的string在做交换时一定会销毁当前空间再开辟新空间存放交换后的数据,但这个需要通过源码确认,待补充

 

posted @ 2022-04-08 19:37  白琉璃  阅读(187)  评论(0)    收藏  举报