即使在超出范围之后,我是否可以保留矢量数据
Can I keep vector data even after out of scope
我来自C背景。我曾经分配内存/数组,例如,将其发送到其他地方,指针留在那里,即使在分配它的范围被破坏之后。
现在,如果我对向量做同样的事情:初始化,通过引用传递它,然后将该引用保存在某个地方。在实际创建向量的初始方法超出范围之后,它会被销毁吗?或者,由于指向它的指针仍然保存,它将被保留。
std::vector
在销毁时释放它所拥有的内存。保留对被破坏的对象的引用是非常糟糕的。访问它是 UB。一般规则:不要存储引用,只在可以确定对象在整个范围内存在的情况下使用它们,例如作为函数的参数。
如果要保留数据的副本,只需复制std::vector
即可。无需参考。
如果您希望能够从不同位置访问数据,并且只要至少一个位置仍有指向它的引用/指针,就让它保持存在,请不要使用std::vector
,使用std::shared_ptr
。
如果您想将std::vector
的好处与共享内存的好处结合起来,共享内存一直存在到最后一个地方放手,请将它们结合起来:std::shared_ptr<std::vector<...>>
.
如果要让std::vector
在一个地方居住一会儿,然后在另一个地方居住,但不再首先居住,请使用移动语义:
std::vector<int> foo = {1, 2, 3};
std::vector<int> bar = std::move(foo); // bar now holds the data that foo held, foo is empty, no copy was performed
指向堆栈上数组的指针不会使数组保持活动状态,我想在 C 中也是如此。现在向量不是数组。它是堆分配数组的包装器,当数组超出范围时,它会释放数组的内存。
。因为指向它的指针仍然保存,它仍然会被保留吗?
不!指向std::vector
的指针或引用不会使矢量保持活动状态。规范错误的例子是:
std::vector<T>& foo() {
std::vector<T> x;
return x;
} // baaam !
从函数返回的引用悬而未决。你对它无能为力。正确的方法是按值返回并依赖于返回值优化:
std::vector<T> foo() {
std::vector<T> x;
return x;
}
如果您这样做:
auto y = foo();
由于 NRVO,不涉及复制。
PS:编译器应该警告您返回对局部变量的引用。
不,如果我对向量做同样的事情,我初始化一个向量,通过引用传递它,然后将引用保存在某个地方。在实际创建向量的初始方法超出范围后,它会被取消吗?
是的。
还是因为指向它的指针仍然保存,它仍然会被保留?
不。
您可以在C++中悬挂指针,就像在 C 中一样。这是完全一样的。
引用通常也是如此(尽管在某些情况下,对象的生存期会延长一点(。
的确,向量的数据由向量在内部管理,但这是顺便的,因为您是在询问向量本身。忘记向量并问关于int
的相同问题,然后你会意识到答案就像你期望的那样在 C 中。
现有的答案很好,将在此处添加:
block A
{
vector<int> my_vec(10, 0);
//...something...
}
block B
my_vec矢量将超出范围并在右括号处销毁。 现在是 stl(标准模板库(向量。
您还可以使用 C 样式数组(但语法不同(。 对于非常大的数组,我发现动态分配数组的分配时间比 STL 向量快。
//static, goes out of scope and memory handled at the end of code block
int arr0[10];
//dynamic, not destroyed unless delete called.
int* arr1 = new int[10];
//...work with arr1...
delete [] arr1;
就像在 C 中一样,您需要注意取消分配使用new
创建的任何内存。
- 是否有内置方法可以强制转换为不同的基础类型,但保留常量限定符?
- C++矢量复制构造函数和赋值运算符是否也复制保留空间?
- 是否有理由在标题中保留完全专用的模板?
- 即使在超出范围之后,我是否可以保留矢量数据
- cin.clear()是否保留EOF
- 访问"std::vector"的保留但未调整大小的内存作为原始内存是否安全?
- 内联函数是否在内联函数中保留其上下文
- 此常量引用是否保留了其生命?
- 如果其他人在等待,是否有标准的STL或QT方法可以产生互惠码,否则请保留它
- 向量是否知道在由一对迭代器初始化时首先保留?
- memcpy是否可以保留不同类型之间的数据
- 我能知道调用方是否保留了共享指针的副本吗?
- 我可以检查内存块(例如,使用 malloc 分配)是否保留在缓存中吗?
- C++默认初始化是否保留先前的零初始化
- unordered_set::erase(pos)是否保留元素的顺序?
- 如果对赋给指针的迭代器进行自增操作,该指针是否保留原始内存位置?
- CString是否保留GetLastError代码?
- 对某些标准流类插入和提取浮点数是否保留其值
- C++发行版是否保留或更新操作上的参数(URNG,params)
- Qt库中的mapreduce是否保留输入文件的顺序?