如何在标准模板库中分配/取消分配对象
How is allocation/deallocation of objects in standard template library done
大多数时候,我对stl对象的分配/释放方式感到困惑。例如:以这个循环为例。
vector<vector<int>> example;
for(//some conditions) {
vector<int>row;
for(//some conditions) {
row.push_back(k); //k is some int.
}
example.push_back(row);
}
在这种情况下,对象行发生了什么。如果我通过示例访问,我仍然可以看到值,这意味着当我执行example.push_back(row)
时,会创建一个新的副本。我说得对吗。有没有一个好的方法来防止同样的情况(如果我是正确的)。
此外,任何人都可以提供参考资料,让我了解stl
中是如何处理分配/释放的,或者避免这种内存复制问题的最佳实践是什么(在大型应用程序的情况下)。
感谢您的帮助。
当我做example.push_back(行)时,会创建一个新的副本。我说得对吗。
是的。
有没有一个好的方法来防止同样的
你为什么要阻止它?这种行为使vector
的使用变得简单和安全。
标准库容器具有值语义,因此它们会复制您添加到其中的值,并管理这些值的生存期,因此您不必担心。
此外,任何人都可以提供参考资料,让我了解stl 中如何处理分配/解除分配
你从来没有听说过搜索引擎吗?尝试http://www.sgi.com/tech/stl/Allocators.html对于初学者来说。
或者避免这种内存复制问题的最佳实践是什么(在大型应用程序的情况下)。
一般来说:忘记它吧。你通常不需要担心它,除非分析显示存在性能问题。
std::vector
确实允许对其内存使用进行更细粒度的控制,请参阅新成员部分和http://www.sgi.com/tech/stl/Vector.html了解更多信息。
对于您的示例,您可以向example
容器添加新行,然后直接向其中添加int
值:
vector<vector<int>> example;
for(/*some conditions*/) {
example.resize(example.size()+1);
vector<int>& row = example.back();
for(/*some conditions*/) {
row.push_back(k); //k is some int.
}
}
更好的做法是提前在矢量中预留足够的容量:
vector<vector<int>> example;
example.reserve( /* maximum expected size of vector */ );
for(/*some conditions*/) {
example.resize(example.size()+1);
vector<int>& row = example.back();
for(/*some conditions*/) {
row.push_back(k); //k is some int.
}
}
stl实现所要做的就是遵守标准。
但std::swap
通常用于将一个向量的内容与另一个向量进行切换。这可以用来防止获取有价值的副本,并且是实现效率的好方法,至少在C++11之前的世界中是这样。(在您的情况下,推回一个空向量,并将其与您创建的向量交换)。
- 使用操作重载对象重新分配对象
- 静态分配对象的值初始化
- C++ 将抽象类型的动态分配对象传递给函数并存储在向量中
- 堆分配对象中的堆栈对象在 c++ 中在哪里分配?
- 在 c++ 的构造函数中分配对象向量时出错
- 动态分配对象中的字段-动态分配更好还是静态分配更好?C++
- 操作后通过运算符分配对象
- 如何捕获源自静态分配对象的构造函数的异常?
- 在C++中,当重新分配对象时,为什么构造函数在析构函数之前触发?
- 如何使用每个对象的单个构造函数参数动态分配C++对象数组?
- 将动态分配对象传递到 boost::any 构造函数中
- 混合指向已分配对象和作用域对象的指针
- C 删除指向动态分配对象的指针
- 有关动态分配对象的问题
- 类的堆分配对象是否在其作用域之后但在 C++ 中调用其析构函数之前处于活动状态
- C++ 中的黑白堆分配对象和堆栈分配对象的性能差异
- 是隐式创建的默认构造函数,负责分配对象内存
- 如何删除用于动态分配对象的智能指针
- 分配对象数组时如何初始化每个对象
- 用于堆栈分配对象的C++虚拟析构函数内联