网站首页 > 资源文章 正文
std::vector的大小是多少?
我们经常使用vector,那么vector到底有多大呢?
我们通过一段代码来看看
#include <vector>
#include <iostream>
int main() {
std::vector<int> emptyVec;
std::cout << "Size of std::vector: " << sizeof(emptyVec) << " bytes" << std::endl;
return 0;
}
上面这段代码
Windows环境Debug下输出32,Release下输出24。
Centos环境输出是24。
std::vector 类模板在 C++ STL 中的实现通常包含几个关键的私有成员变量,它们用于管理存储和访问元素所需的数据。这些成员包括:
一个指向当前存储区域起始位置的指针。
一个指向当前存储区域末尾(即下一个可写入位置)的指针。
一个指向存储区域结束(即分配的存储容量的末尾)的指针。
有时还包括一个表示当前元素数量的计数器。
由于 std::vector 是一个模板类,其对象的实际大小依赖于元素的类型和编译器的对齐规则。即使 std::vector 完全为空,它仍然需要存储上述管理信息。因此,即使没有存储任何元素,std::vector 本身也会占据一定量的内存。
我们看一下GCC的vector源码,可以看到这里面有三个指针作为成员变量,所以大小是三个指针的大小也就是24个字节。
三个指针分别表示:
目前使用空间的头
目前使用空间的尾
目前可用空间的尾
Windows环境Debug下多了8个字节,是因为在调试环境中,C++ 标准库(如 MSVC 的实现)可能会为 std::vector 添加额外的成员或元数据,以便提供更好的错误检测和调试支持。
对于vector有个知识点:
动态增加大小,不是在原空间后面接连续的新空间,因为无法保证原来的空间后面有足够的空间。所以vector是以原来大小的两倍重新申请一块较大空间,然后把原来的内容拷贝过来,之后再构造新元素。
对vector的任何操作,只要发生了动态配置,那么指向原来vector的所有迭代器就都失效了。在删除元素的时候,经常犯这个错误。
std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto it = vec.begin(); it != vec.end(); ++it)
{
if (*it == 2)
{
vec.erase(it);
}
}
// 错误:可能未到达 `vec.end()`
上面的代码就是经典的一个删除元素错误。
问题分析
在初始状态下,it 指向 vec 的第一个元素,即 1。
当 *it == 2 时,循环体内执行 vec.erase(it)。这意味着当 it 指向 2 时,2 会被删除。
vec.erase(it) 会删除当前迭代器指向的元素,并返回一个新的迭代器,指向删除元素后的位置。
问题点:vec.erase(it) 被调用后,it 仍然是指向已删除元素的位置。但是,原始代码中并没有更新 it 的值。
接下来,++it 会使 it 指向 2 之后的元素。然而,由于 2 已经被删除,实际上 it 现在指向了一个不存在的位置。
举例说明
假设 std::vector<int> vec = {1, 2, 3, 4, 5}。
初始时,it 指向 1。
循环第一次迭代时,it 指向 1,条件不满足,it 指向 2。
循环第二次迭代时,it 指向 2,条件满足,2 被删除。
问题:此时 it 仍然指向 2 的位置,但是 2 已经被删除,因此 it 指向的位置实际上是无效的。
接下来的 ++it 使得 it 指向 2 之后的元素,即原本的 3 的位置。但是,由于 2 已经被删除,it 实际上指向了 4 的位置,跳过了原本的 3。
(执行删除后,原来的整个迭代器已经全部失效,vec现在变成了{1,3,4,5})
正确做法如下:
std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto it = vec.begin(); it != vec.end();)
{
if (*it == 2)
{
it = vec.erase(it);
} else
{
++it;
}
}
猜你喜欢
- 2024-10-29 C++遍历vector元素的四种方式(c++ iterator遍历)
- 2024-10-29 c++vector常用操作及函数(c++ vector常用方法)
- 2024-10-29 Vector冲锋枪:极富科技感的未来军械
- 2024-10-29 绝地求生:汤姆逊或超越M4成玩家最爱?Vector居然加入空投了!
- 2024-10-29 绝地求生Vector(当对面掏出短剑的时候,你已经凉了)
- 2024-10-29 std::vector的用法,删除,添加,更新成员?
- 2024-10-29 C++ Vector类型及使用(c++vector详解)
- 2024-10-29 数据安排与操作方式:vector的扩容操作
- 2024-10-29 C++中的动态内存管理:深入探讨std::vector与指针
- 2024-10-29 vector的底层是如何实现的?#代码(vector的原理)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- 电脑显示器花屏 (79)
- 403 forbidden (65)
- linux怎么查看系统版本 (54)
- 补码运算 (63)
- 缓存服务器 (61)
- 定时重启 (59)
- plsql developer (73)
- 对话框打开时命令无法执行 (61)
- excel数据透视表 (72)
- oracle认证 (56)
- 网页不能复制 (84)
- photoshop外挂滤镜 (58)
- 网页无法复制粘贴 (55)
- vmware workstation 7 1 3 (78)
- jdk 64位下载 (65)
- phpstudy 2013 (66)
- 卡通形象生成 (55)
- psd模板免费下载 (67)
- shift (58)
- localhost打不开 (58)
- 检测代理服务器设置 (55)
- frequency (66)
- indesign教程 (55)
- 运行命令大全 (61)
- ping exe (64)
本文暂时没有评论,来添加一个吧(●'◡'●)