- 论坛徽章:
- 0
|
本帖最后由 Frahm 于 2013-04-12 00:14 编辑
我想把一个pool封装成符合stl标准的allocator,所以在自己写的allocator内部private区加了一个pool对象,因为内存是被pool管理的,所以内存是在pool被析构的时候释放所有pool中的内存,然而这个封装完的allocator在给std::vector和std::list用时,会诡异地崩掉,我可以保证pool这个类是正常工作的,我感觉问题就是出在allocator被析构的时候,这时我把它分配的内存都回收了,我感觉这应该很合理才对,因为allocator被析构说明由它分配的内存不会被使用,否则析构后不可能调用deallocate()回收,为此我写了一个模仿pool类行为的测试用allocator, 它在被析构时也会释放所有申请的内存,在std::vector和std::list的测试下,也都崩溃。
那么这是怎么一回事呢?
下面的是测试用的会出问题的allocator代码:
- template<typename T>
- class FakePool {
- public:
- typedef T value_type;
- typedef T* pointer;
- typedef const T* const_pointer;
- typedef T& reference;
- typedef const T& const_reference;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
- template<typename U>
- struct rebind {
- typedef FakePool<U> other;
- };
- public:
- FakePool() {
- std::cout << typeid(*this).name() << " constructed\n";
- }
- template<typename U>
- explicit FakePool(const FakePool<U>&) {}
- ~FakePool() {
- std::cout << typeid(*this).name() << " destructed\n";
- for(void* ptr : ptrs_) {
- ::operator delete(ptr);
- }
- }
- pointer allocate(size_type n, const void* = nullptr) {
- void* ptr = ::operator new(sizeof(T) * n);
- ptrs_.push_back(ptr);
- return (pointer)ptr;
- }
- void deallocate(pointer ptr, size_type) {
- Assert(ptr != nullptr);
- auto iter = std::find(ptrs_.begin(), ptrs_.end(), ptr);
- Assert(iter != ptrs_.end());
- ptrs_.erase(iter);
- ::operator delete(ptr);
- }
-
- inline void construct(pointer ptr, const_reference copy) {
- new(ptr) T(copy);
- }
- inline void destroy(pointer ptr) {
- ptr->~T();
- }
- inline pointer address(reference val) const {
- return std::addressof(val);
- }
- inline const_pointer address(const_reference val) const {
- return std::addressof(val);
- }
- inline size_type max_size() const {
- return (size_type)(-1) / sizeof(T);
- }
- private:
- std::vector<void*> ptrs_;
- };
- //测试代码
- int main() {
- {
- std::list<int, core::FakePool<int> > myls;
- myls.push_back(12);
- std::cout << myls.front() << '\n';
- }
- return 0;
- }
复制代码 注: Assert是我写的类似assert的函数 |
|