如果我不服从无国籍的自定义分配器教条会发生什么?

时间:2010-11-05 21:34:31

标签: c++ memory-management c++11

我需要为std :: objects创建一个自定义分配器(特别是最初用于std :: vector)但最终可能会使用其他的

我需要创建自定义分配器的原因是我需要通过应用程序的各个组件跟踪分配的(堆和堆栈)资源(这是应用程序的固有功能)。我将需要自定义分配器来监视资源的堆部分,因此我必须能够传递给std :: vector构造函数,如

trackerId idToTrackUsage;
myAlloca<int> allocator(idToTrackUsage);
vector<int> Foo( allocator );

然而,在阅读了一下后,我发现了关于STL / C ++标准的小炸弹(参见参考资料),说给定类型的所有分配器实例都应该是等价的(即= =应该对任何两个实例返回true)而且,大多数终端;任何分配器都应该能够释放由任何其他实例分配的内存(也就是说,无需知道其他实例可能是什么)。简而言之,分配器不能拥有状态。

所以我试图找到解决这个问题的最佳方法。任何聪明的想法?我真的真的不想保持std :: vector的自定义版本。

编辑:我在http://www2.research.att.com/~bs/C++0xFAQ.html#scoped-allocator上读到了关于c ++ 0x的作用域分配器,但我真的无法理解这是如何适用于我的问题的。如果有人认为c ++ 0x缓解了这个问题,请发表评论

参考文献:

Allocator C++ article in Wikipedia

Some random further reading courtesy of Google

4 个答案:

答案 0 :(得分:5)

除了显而易见的答案(“如果你违反了任何要求,那是未定义的行为,晚安并感谢你的演奏”),我想象可能发生的最差是{{ 1}}实现可以依赖于“分配器类的所有实例都可以互换”的要求,显而易见:

vector

查看源代码,GCC的向量实现(我认为它最终基于SGI的原始STL实现)确实存储了传递给该构造函数的allocator对象的副本,因此有一些希望不会发生这种情况。

我会说尝试看看,并非常仔细地记录你所做的 ,以便任何试图在你未检查的实现上使用你的代码的人知道发生了什么上。标准中鼓励实施者放松对分配器的限制,因此,如果他们不是放松的话,那就好像让他们放松一样。这并不意味着它不会发生。

如果你真的很幸运,那么你的容器实现有一些文档可以讨论分配器。

答案 1 :(得分:3)

当然,你可以在任何已分配的块中留下指向所需状态的指针。这当然意味着任何每块状态都必须存储在该块中,并且分配器实例的行为更像是句柄而不是实际对象本身。

答案 2 :(得分:1)

如果你能够使用它,那么使分配器状态保持静态就可以了。它确实意味着 type 的所有分配器都必须共享它们的状态,但是根据您的要求,这听起来似乎是可以接受的

答案 3 :(得分:1)

要响应您的编辑:是的,在C ++ 0x或C ++ 11中,分配器可以具有状态。