为什么std :: vector没有释放方法?

问题描述 投票:2回答:5

我发现自己想在unique_ptr中使用release()std::vector<>类似物。例如:

std::vector<int> v(SOME_SIZE);

//.. performing operations on v

int* data = v.release(); // v.size() is now 0 and the ownership of the internal array is released
functionUsingAndInternallyDeletingRowPointer(data);

是否有特定原因无法提供这种可能性?这可能会对std::vector的内部实现施加一些限制吗?

或者有一种方法可以使我尴尬地丢失?

c++ vector stl std allocator
5个回答
1
投票

可能会对std :: vector的内部实现施加一些约束吗?

以下是一些可能与此冲突的示例:

  • 除非有特殊情况,否则底层内存分配不能new T[]获得,也不会由delete[]销毁,因为它们将在已分配但实际上不应包含任何对象的内存上调用构造函数和析构函数。输入T
  • 数组的开头可能实际上不是内存分配的开头;例如向量可以在数组开始之前存储簿记信息
  • vector销毁后实际上可能不会释放内存;例如取而代之的是,分配可能来自小型数组池,该实现用于实现快速创建和销毁小型向量。 (此外,这些数组都可能只是更大数组的切片)

4
投票

functionUsingAndInternallyDeletingRowPointer

这个函数到底会做什么?因为该内存是通过调用std::allocator_traits<std::allocator<T>>::allocate分配的,所以期望通过调用std::allocator_traits<std::allocator<T>>::deallocate将其删除。此外,vector的每个元素都是通过调用std::allocator_traits<std::allocator<T>>::construct构造的,因此必须通过调用std::allocator_traits<std::allocator<T>>::destroy销毁。

如果该函数尝试对该指针执行delete [],则它将无法正常工作。或者至少,它不是required起作用。

能够从vector中提取内存缓冲区并直接使用它可能是合理的。但这不能仅仅是一个指针。它必须要有一个分配器。


2
投票

我有两个原因可以想到:

  1. 最初(C ++ 11之前的版本),vector与小对象优化兼容。也就是说,如果它的大小足够小,它可能已经指出了它自己。在C ++ 11中无意中禁用了此功能(vector的移动语义禁止引用/迭代器无效),但在将来的标准中可能已修复。因此,没有理由在历史上提供它,并且希望将来不会提供。
  2. 分配器。如果通过分配器传递了一个指向载体的指针,那么您的函数可能会调用未定义的行为]]

1
投票

这是在N4359中提出的,但事实证明,存在一些细微的问题,这些问题会给调用者带来负担,以避免错误的行为(似乎主要与分配器有关)。有关困难和可能替代方法的讨论可以找到here。最终它被C ++标准组织拒绝。进一步的讨论可以在评论this question及其答案中找到。


0
投票

我能够使用自定义分配器实现检索当前分配数组的功能。以下代码显示了概念:

© www.soinside.com 2019 - 2024. All rights reserved.