c++ vector动态增长陷阱

203 阅读1分钟

1 代码文件

编译并运行,会发现Node的析构函数被调用超过10次。

#include <iostream>
#include <vector>

class Node {
 public:
  Node(int i) : i_(i) { std::cout << "默认构造: " << i_ << std::endl; }
  Node(Node& n) : i_(n.i_) { std::cout << "拷贝构造: " << i_ << std::endl; }
  Node(Node&& n) : i_(n.i_) { std::cout << "移动构造: " << i_ << std::endl; }

  ~Node() { std::cout << "析构: " << i_ << std::endl; }

 private:
  int i_;
};

int main() {
  std::vector<Node> v;
  std::cout << "开始遍历" << std::endl;
  for (size_t i = 0; i < 30; i++) {
    v.emplace_back(i);
    std::cout << "vector 大小: " << v.size() << " 容量: " << v.capacity()
              << std::endl;
  }
  std::cout << "结束遍历" << std::endl;
}

2 vector动态增长

  • 观察输出,会发现vector容量按1、2、4、8、16...的增长速度扩增

  • 我们知道vector的数组存储空间在内存中是一段连续的地址

  • 当vector元素个数超过vector的容量时,会自动申请一段更长的内存地址。

  • 在新地址上调用元素的移动构造函数,旧地址上的析构函数被调用。

本文使用 markdown.com.cn 排版