几年前我刚刚遇到了前同事写的一段代码。老实说,我不是C ++专家,所以我正在寻求帮助。
代码如下所示:
std::vector<OBJ> objects;
void initobjs()
{
for (int i=0; i<10; i++)
{
OBJ obj;
obj.type=i;
obj.len=16;
objects.push_back(obj);
}
}
我的问题是:在函数initobjs()
返回后,是不是所有obj
个实例都已超出范围并被C ++运行时系统自动释放?如果是,是否会对添加到向量中的任何对象的内容进行引用会导致内存错误或意外结果?
答案 0 :(得分:13)
您的关注可以更加本地化:obj
在for-loop的底部结束。
也就是说,容器生成其参数*的副本,并且不存储任何引用或指向“原始”值的指针。
*因此,所有容器都要求其元素可以复制构造并可复制分配。
答案 1 :(得分:7)
原始对象将超出范围,但push_back()
方法实际上创建了它们的副本,因为它们是按值传递的。因此,当initobjs()
函数退出时,副本仍然在向量中;将它们从向量中移除时,或者当向量本身超出范围时,它们将被释放。
如果向量是vector<OBJ*>
,那么这将是一个完全不同的事情:这意味着你必须在从向量中删除它时手动删除每个对象(除非你将它存储在别处)。
请注意,C ++根本没有内置任何内存管理,除了堆栈分配的变量,这些变量在其范围结束时被释放。 RAII是你正在寻找的热门词汇,以防你想要更多地启发自己。
答案 2 :(得分:1)
objects
向量将包含for循环中OBJ
的“副本”。根据{{1}}的复制构造函数的不同,这可能会产生适当的结果。
我会去检查OBJ
的复制构造函数是否有疑问。