gpt4 book ai didi

C++ 分配器和内存池所有权

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

我对某事感到困惑。假设我有一个任意的 C++ 分配器——比如说,像这样:

template<class T>
struct my_allocator
{
template<class Other>
struct rebind { typedef my_allocator<Other> other; };

// [other members here]
};

现在考虑以下代码(请阅读注释):

typedef my_allocator<int> Alloc;
Alloc alloc = get_my_allocator(); // assume this works properly

long *const p = Alloc::rebind<long>::other(alloc).allocate(1, NULL);
// Notice that the rebound allocator for 'long' is now destroyed

// Can a NEW rebound allocator for 'long' deallocate the memory from the old one?
Alloc::rebind<long>::other(alloc).deallocate(p, 1);
// i.e., does the 'int' allocator 'alloc' keep alive the 'long' memory pool too?

究竟在什么时候可以释放后备存储池?

或者,换一种说法:哪个分配器共享哪个内存池的所有权

我一直假设 - 没有太多考虑 - 相同值类型的分配器共享他们自己的内存池的所有权,但现在我想到了他们也可以共享所有 rebound 分配器后面的内存池的所有权,即使它们管理完全不同的类型。

反弹类型的分配器是否必须“保持活跃”彼此的内存池,直到它们全部被销毁?

如果 C++03 和 C++11 的答案不同,请说明两者以及它们之间的区别。

最佳答案

Must allocators of rebound types "keep alive" each others' memory pools until all of them are destroyed?

简短的回答是肯定的,尽管有一些警告。长答案如下...


C++11(和 C++14)说 [allocator.requirements] my_allocator<long>my_allocator<int> 构成必须能够删除从 my_allocator<int> 分配的内存.这在分配器要求表中表示为:

X a(b);

后置条件为:

Y(a) == b and a == X(b)

如你所知,operator== 在这里用来表示:两个相等的分配器可以释放彼此分配的指针。还有表文件bY 类型的对象在哪里 XY是由 rebind 相关的分配器如上所示。

现在,仅此一项并不能确定您的确切问题,如您的问题 my_allocator<int>从不实际分配任何东西。然而,同一张表中的另一行继续说明分配器的运算符==:

a1 == a2

后置条件:

returns true only if storage allocated from each can be deallocated via the other. operator== shall be reflexive, symmetric, and transitive, and shall not exit via an exception.

(重点是我自己的)

传递性意味着如果a1 == a2,并且a2 == a3,则暗示a1 == a3。

这个细节说明了你的问题。第一个临时my_allocator<long>复制自 alloc因此等于alloc .

第二个临时my_allocator<long>也复制自 alloc ,因此也等于 alloc .此外,由于传递性,两个临时 my_allocator<long>也必须彼此相等。

这并不完全意味着它们都必须共享同一个内存池。但这确实意味着所有这三个分配器都必须能够以某种方式释放彼此分配的指针。 IE。你的例子需要工作。

C++03 缺少“传递”要求。话虽如此,在 C++11 措辞中添加“传递性”被认为仅仅是对 C++03 意图的“清理”,而不是新的要求。因此,语言律师可以争论 C++98/03 中是否需要传递,但从实际的角度来看,代码最好假设它是,因为这是意图。

确实,C++98/03 也包含了这种“鼬鼠”的措辞(C++11/14 中不再存在):

All instances of a given allocator type are required to be interchangeable and always compare equal to each other.

即允许 C++98/03 容器假设所有实例(实际上甚至反弹实例)总是相等。直到 C++11 才真正开始对“有状态”分配器的官方支持。

关于C++ 分配器和内存池所有权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24803430/

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