【问题标题】:boost::ptr_vector with arrays: Can I be sure that its destructor calls delete[] instead of delete?boost::ptr_vector 与数组:我可以确定它的析构函数调用 delete[] 而不是 delete?
【发布时间】:2012-02-17 10:58:22
【问题描述】:

我有以下情况:

boost::ptr_vector<float> vec;

float* array = new float[4]();
vec.push_back(array);

// Add some more elements to vec..

我如何确保如果我离开这个范围并且 vec 将被销毁,ptr_vector 的析构函数调用 delete[] 而不是 deletevec 的每个元素上调用。我不明白它应该如何工作,因为 float*float[4] 的模板参数 float 相同。

【问题讨论】:

  • 如果您可以使用,std::vector&lt;std::unique_ptr&lt;float[]&gt;&gt; 可以解决问题。

标签: c++ memory-management boost


【解决方案1】:

您可以将ptr_vectorCloneAllocator 模板参数指定为默认值heap_clone_allocator 以外的其他值。无法使实际类boost::ptr_vector&lt;float&gt; 的实例使用delete[] 而不是delete

【讨论】:

  • 是的,我知道这一点。但是像 view_clone_allocator 这样的另一个分配器不执行释放。但是我该怎么做才能拥有像 ptr_vector 这样的功能,它使用 delete[] 删除其包含的数组?应避免使用 std::vector 并遍历其元素,并在每个元素上调用 delete[]。
  • @morph:我认为 Boost 没有提供适合这种情况的解决方案,因此请编写您自己的克隆分配器。大概他们不提供的原因是他们认为包含指向 C 数组的指针的 ptr_vector 不是很有用——它有点难看,因为 ptr_vector 访问器只给你每个数组的第一个元素的引用。我猜你最终会写(&amp;my_vector[0])[1],维护一个带有大小的单独容器,以及其他类似的肮脏。如果数组的大小都是 4,则使用 boost::array&lt;float,4&gt;vectorptr_vector
【解决方案2】:

对于包含int BUILT-IN 简单类型项目(如float 或char)的数组:我认为delete 和delete[] 之间没有区别,因为delete[] 假定调用许多析构函数——对于数组的每个对象,但是内置原始类型不假定调用析构函数 - 那里没有什么可以破坏的;释放浮点数组只是释放固态内存,而不执行任何可能放置在某种析构函数中的代码。咕噜……

【讨论】:

  • Hm.. 我学会了对使用 operator new 创建的指针调用 delete 并在使用 operator new[] 创建的数组上调用 delete[]。
  • 在分配有new[] 的数组上使用delete(反之亦然)会产生未定义的行为。
  • 你对“书中所写的内容”是正确的,但我说的是“它在现实中是如何运作的”。
  • @pavelkolodin:考虑一个实现,其中数组形式存储分配的大小,而单对象形式从对象大小推断它。错误调用delete 会推断出错误的大小,因此可能会浪费大块内存;错误地调用delete[] 将读取无效的大小,这几乎可以使任何事情发生。如果您尝试依赖对未定义行为的猜测,这只是一个可能出错的实现示例。
  • 正如 Mike Seymour 所说,问题在于分配的大小,以及是否可以在删除时知道,或者是否必须存储。 delete 和 delete[] 是不同的运算符是有原因的。缺点不仅仅是丢失了内存,它是一个损坏的堆。
猜你喜欢
  • 2013-06-25
  • 2011-01-12
  • 2017-02-15
  • 1970-01-01
  • 2014-11-22
  • 2018-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多