C++ STL vector erase函数中,有没有重新分配内存?
1erase函数有没有重新分配内存,释放原有数组空间?2v.erase(remove(v.begin(),v.end(),0),v.end())请问这个有没有重新分配内存...
1 erase函数有没有重新分配内存,释放原有数组空间?
2 v.erase( remove( v.begin(), v.end(), 0) , v.end() )
请问这个有没有重新分配内存?为何我这教程上说,即使用先前的迭代器也不会出现访问到不存在元素的错误(这意思就是说,没有重新分配内存?)
3 教程里还说,为了实现删除元素后容器自动缩小,每次erase后,向量要重新分配内存,并复制所有元素。
这极大的影响性能。因为标准库把释放内存的选择交给了程序员,让程序员选择放还是不放。你可以使用
v.swap(vector<T>(v)) 来释放多余的内存。
对于第3点,有疑问:
1、erase既然重新分配了,难道他没有自动释放原来的空间?如果自动释放了,那么从何而来的让程序员决定是否释放?
2、swap是交换,跟释放多余的空间,在这里扯上什么关系? 展开
2 v.erase( remove( v.begin(), v.end(), 0) , v.end() )
请问这个有没有重新分配内存?为何我这教程上说,即使用先前的迭代器也不会出现访问到不存在元素的错误(这意思就是说,没有重新分配内存?)
3 教程里还说,为了实现删除元素后容器自动缩小,每次erase后,向量要重新分配内存,并复制所有元素。
这极大的影响性能。因为标准库把释放内存的选择交给了程序员,让程序员选择放还是不放。你可以使用
v.swap(vector<T>(v)) 来释放多余的内存。
对于第3点,有疑问:
1、erase既然重新分配了,难道他没有自动释放原来的空间?如果自动释放了,那么从何而来的让程序员决定是否释放?
2、swap是交换,跟释放多余的空间,在这里扯上什么关系? 展开
1个回答
展开全部
没有重新分配。但是后续的元素被往前移动,因此被删除的元素之后的迭代器会失效。例如,下面的代码在debug模式下将会崩溃,在release模式下正常运行而且可以看到数组的地址并没有改变。
#include <vector>
#include <iostream>
int main(){
std::vector<int> v{ 1, 2, 3, 4, 5, 6, 7 };
auto p = v.end() - 2;
std::cout << &v[0] << "\t" << *p << "\t" << &*p << "\n";
v.erase(v.begin() + 2);
std::cout << &v[0] << "\t" << *p << "\t" << &*p << "\n";
return 0;
}
v.swap(vector<T>(v));将v复制到新的向量中(这个向量的容量正好和v的大小一样),然后与v进行交换。因为这是一个局部变量,所以这句话结束时会将从v处获得的内存释放。同时,v在交换之后,容量和大小一致。
建议你看一下源代码,或者单步调试看看具体的执行过程。
更多追问追答
追问
既然没有重新分配,那么怎么会失效呢?因为你空间大小没变嘛,被删除元素之后,原来如果还有分配的空间,那么有效,原来如果没空间,那么无效。
然而,又哪里来的从有效到无效?
还有,不懂上面的代码为何会崩溃,毕竟开辟的空间大小不变,不管删了没,p指向的始终是自己分配的空间,这又怎么会指针越界而崩溃呢?
追答
你的说法可以解释release模式为什么没崩溃。debug检查得更严格,p本来应该指向6,但是erase之后指向了7。也就是说,它不再指向原来的元素了,从这个意义来说失效了。特别地,如果p一开始指向7,那么erase之后,就指向到了边界外,出现越界,因此也算失效。
注:erase会把数组变小(不同于内存的大小)。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询