C++中vector插入自定义对象时析构次数逐次增加的原因是什么
C++对象析构次数异常原因解答
这个现象是std::vector的动态扩容机制导致的,具体运行逻辑如下:
std::vector是采用连续内存存储元素的容器,当现有容量不足以容纳新插入的元素时,会自动申请一块更大的新内存空间(不同STL实现的扩容步长有区别,常见为原容量的1.5~2倍,部分极简实现可能每次仅扩容1个元素大小),将原内存中的所有元素逐个拷贝到新内存后,会析构原内存中的全部旧元素,再释放原内存空间。- 你每次输入后的执行流程完全匹配你看到的输出:
- 第一次输入
c 18:
- 构造局部对象
thedata - 空vector初始容量为0,申请1个元素的内存,拷贝
thedata存入vector - 循环结束,局部对象
thedata析构,打印1次Object destroyed,和你的预期一致
- 第二次输入
d 15:
- 构造局部对象
thedata - vector现有容量为1,不足以存储第2个元素,触发扩容,申请新内存后拷贝原有1个元素到新内存,析构原内存中的1个旧元素(额外多打印1次)
- 拷贝新的
thedata存入vector末尾 - 循环结束,局部对象
thedata析构,本次总共打印2次
- 第三次输入
a 14:
- 构造局部对象
thedata - vector现有容量为2,不足以存储第3个元素,触发扩容,拷贝原有2个元素到新内存后,析构原内存中的2个旧元素(额外多打印2次)
- 拷贝新的
thedata存入vector末尾 - 循环结束,局部对象
thedata析构,本次总共打印3次
- 第四次输入
b 21:
- 构造局部对象
thedata - vector现有容量为3,不足以存储第4个元素,触发扩容,拷贝原有3个元素到新内存后,析构原内存中的3个旧元素(额外多打印3次)
- 拷贝新的
thedata存入vector末尾 - 循环结束,局部对象
thedata析构,本次总共打印4次
- 第一次输入
- 额外注意:你代码里的范围for循环
for (Name_value x : v)采用值拷贝接收元素,每次迭代都会生成一个元素的临时拷贝,迭代结束后这个临时拷贝会被析构,等你输入结束触发EOF跳出while循环后,还会额外打印4次Object destroyed;程序退出前vector销毁时,还会析构内部存储的4个元素,再打印4次。
优化方案
你可以通过以下修改避免不必要的析构:
- 提前给vector预留足够容量,避免频繁扩容:在main函数开头插入
v.reserve(100);(数值按需调整为你预计的最大元素数量即可),修改后每次while循环只会析构局部的thedata对象,每次仅打印1次,符合你的预期 - 用
emplace_back代替push_back,直接在vector的内存空间上构造对象,不需要创建局部临时对象:将v.push_back(thedata);替换为v.emplace_back(name, score);,同时可以删除局部对象thedata的定义,进一步减少一次拷贝和析构 - 范围for循环改用常量引用接收元素,避免不必要的拷贝:修改为
for (const Name_value& x : v)
内容的提问来源于stack exchange,提问作者jaylse2
相关产品推荐
相关产品推荐

