gpt4 book ai didi

c++ - 为什么在 C++11(涉及分配器)中交换标准库容器会出现问题?

转载 作者:IT老高 更新时间:2023-10-28 22:59:58 25 4
gpt4 key购买 nike

注意:最初由 GreenScape 提出如comment .


看完Why are the swap member functions in STL containers not declared noexcept?似乎在为标准容器执行 a.swap(b) 时潜在的未定义行为的原因归结为也交换或不交换底层分配器。

  • 为什么交换分配器和数据会出现问题?

最佳答案

让我们从深入研究标准(N3797)开始:

23.2.1p9 General Container Requirements [container.requirements.general]

If allocator_traits<allocator_type>::propagate_on_container_swap::value is true, then the allocators of a and b shall also be exchanged using an unqalified call to non-member swap. Otherwise, they shall not be swapped, and the behavior is undefined unless a.get_allocator() == b.get_allocator().


propagate_on_container_swap的目的是什么? ?

如果分配器有一个名为 propagate_on_container_swaptypedefstd::true_type被交换的两个容器的底层分配器也将交换。[1]

如果 propagate_on_container_swapstd::false_type只有两个容器的数据会交换,但分配器会留在原处。

[1] 这意味着在 a.swap(b) 之后, a.get_allocator()将是以前的 b.get_allocator() ;分配器已交换


有状态分配器的含义是什么?

分配器不仅负责为标准容器中的元素分配内存,还负责释放所述元素。

C++03 不允许在标准容器中使用有状态分配器,但 C++11 要求必须提供对此类的支持。这意味着我们可以定义一个分配器,根据它的构造方式,它以某种方式起作用。

如果分配器有 propagate_on_container_swap::value等于 false所涉及的两个分配器之间的状态差异可能会导致未定义的行为,因为分配器的一个实例可能与另一个分配器处理的数据不兼容。


如果有状态分配器没有正确交换,它们可能会出现什么问题?

假设我们有一个 MagicAllocator哪个使用 mallocoperator new分配内存,取决于它的构造方式。

如果它使用 malloc要分配内存,它必须使用 free解除分配,如果是 operator new , delete是必须的;因此,它必须保留一些信息,说明它应该使用两者中的哪一个。

如果我们有两个 std::vector两者都使用MagicAllocator但有不同的状态(意味着一个使用 malloc 和另一个 operator new ),我们不会在 a.swap(b) 上交换分配器分配器与交换后为两个 vector 中的元素分配的内存不匹配 - 这意味着错误的 free/delete可能会在释放时调用。

关于c++ - 为什么在 C++11(涉及分配器)中交换标准库容器会出现问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23757166/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com