std::vector的疑问

疑问

std::vector 内部大致长这样
class vector {
int* data_;
size_t size_;
size_t capacity_;
}; 请问data_、size_和 capacity_的作用是什么

1. data_

  • 作用指向动态分配的内存的指针
  • 详细解释data_ 是 vector 所有元素的“家”。它指向一块在堆(heap)上通过 new[] 分配的连续内存空间。vector 的所有元素都顺序存储在这块内存里。因为是指向数组的指针,所以可以通过 data_[index] 的方式直接访问元素,这与普通数组 arr[index] 的访问方式完全一致,保证了高效性。
  • 示例:对于一个存储了 {1, 2, 3, 4, 5} 的 vector,data_ 指向的内存布局如下:
    data_ -> [1] [2] [3] [4] [5]
    

2. size_

  • 作用当前 vector 中实际拥有的元素数量
  • 详细解释size_ 表示用户通过 push_back, emplace_back, insert 等操作成功添加到 vector 中的元素个数。它是 vector::size() 方法的返回值。你只能访问和修改索引在 [0, size_ - 1] 范围内的元素。访问 data_[size_] 及之后的内存是未定义行为(Undefined Behavior),尽管那块内存可能确实被分配了。
  • 示例:继续上面的例子,size_ 的值是 5vector[4](即 data_[4])是有效的,值为 5;而 vector[5](即 data_[5])是无效的,可能导致程序崩溃。

3. capacity_

  • 作用当前 vector 已分配的内存最多可以容纳的元素数量
  • 详细解释capacity_ 表示 data_ 所指向的那块内存的总容量。为了保证追加元素时的高效(避免每次 push_back 都重新分配内存),vector 通常会分配比当前所需(size_)更多的内存。capacity_ 就是这块“预留”内存的边界。它是 vector::capacity() 方法的返回值。
  • 关键关系size_ <= capacity_ 始终成立。
  • 示例:当 vector 内部进行扩容时(例如,当前 size_ == capacity_ 时再次 push_back),它会执行以下操作:
    1. 分配一块新的、更大的内存(新容量通常是旧容量的 1.52 倍)。
    2. 将旧内存中的所有元素([0][size_-1])复制或移动到新内存。
    3. 释放旧内存。
    4. data_ 指向新内存。
    5. 更新 capacity_ 为新的容量值。
    6. 然后才执行插入新元素的操作并增加 size_

总结与类比

你可以用一个搬家的比喻来理解这三者:

  • data_:就是你新家的地址
  • capacity_:是你的新家的总面积(例如 100 平方米)。
  • size_:是你已经搬进去的家具数量(例如 60 件)。
特性 data_ (地址) size_ (已搬家具数) capacity_ (房屋总面积)
作用 定位元素存储位置 表示有效元素个数 表示内存总容量
可变性 扩容时改变 增删元素时改变 扩容或 shrink_to_fit 时改变
访问限制 不能直接访问 [size_] 之后 索引必须 < size_ 无直接访问关系
方法返回 .data() .size() .capacity()

一个简单的过程示例:

  1. vector<int> v;data_ = nullptrsize_ = 0capacity_ = 0
  2. v.push_back(1);: 需要扩容。分配(比如)1 个元素的内存。
    • data_ = 新地址
    • capacity_ = 1
    • 存入 1size_ = 1
  3. v.push_back(2);size_(1) == capacity_(1),需要再次扩容。分配(比如)2 个元素的新内存。
    • 1 复制到新内存
    • data_ = 新新地址
    • capacity_ = 2
    • 存入 2size_ = 2
  4. v.push_back(3);size_(2) == capacity_(2),继续扩容。分配(比如)4 个元素的新内存。
    • 1, 2 复制到新内存
    • data_ = 新新新地址
    • capacity_ = 4
    • 存入 3size_ = 3

此时,状态为:size_ = 3(有3个元素),capacity_ = 4(还能再放1个元素不用扩容)。

posted on 2026-03-26 16:23  四季萌芽V  阅读(3)  评论(0)    收藏  举报

导航