一个可以跨 dll 使用的 allocator

参照Stephan T. Lavavej 写的 Mallocator,自己写了一个 allocator,用于跨 dll 分配和释放字符串
  1. #pragma once
  2. // The following headers are required for all allocators.
  3. #include <stddef.h>  // Required for size_t and ptrdiff_t and NULL
  4. #include <new>       // Required for placement new and std::bad_alloc
  5. #include <stdexcept> // Required for std::length_error
  6. // The following headers contain stuff that allocator uses.
  7. #include <iostream>  // For std::cout
  8. #include <ostream>   // For std::endl
  9. template <typename T>
  10. class pheap_allocator
  11. {
  12. public:
  13.     // The following will be the same for virtually all allocators.
  14.     typedef T       *pointer;
  15.     typedef const T *const_pointer;
  16.     typedef T       &reference;
  17.     typedef const T &const_reference;
  18.     typedef T       value_type;
  19.     typedef size_t  size_type;
  20.     typedef ptrdiff_t difference_type;
  21. public:
  22.     // Default constructor, copy constructor, rebinding constructor, and estructor.
  23.     // Empty for stateless allocators.
  24.     pheap_allocator() {}
  25.     pheap_allocator(const pheap_allocator&) {}
  26.     template <typename U> pheap_allocator(const pheap_allocator<U>&) {}
  27.     ~pheap_allocator() {}
  28.     pointer address(reference r) const { return &r; }
  29.     const_pointer address(const_reference s) const { return &s; }
  30.     size_type max_size() const
  31.     {
  32.         // The following has been carefully written to be independent of
  33.         // the definition of size_t and to avoid signed/unsigned warnings.
  34.         return (~static_cast<size_type>(0)) / sizeof(T);
  35.     }
  36.     bool operator != (const pheap_allocator& other) const { return !(*this == other); }
  37.     // Returns true if and only if storage allocated from *this
  38.     // can be deallocated from other, and vice versa.
  39.     // Always returns true for stateless allocators.
  40.     bool operator == (const pheap_allocator& other) const { return true; }
  41.     void construct(T * const p, const_reference t) const
  42.     {
  43.         void * const pv = static_cast<void *>(p);
  44.         new (pv) T(t);
  45.     }
  46.     void destroy(T * const p) const// Defined below.
  47.     // The following will be different for each allocator.
  48.     pointer allocate(const size_type n) const
  49.     {
  50.         std::cout << "Allocating " << (unsigned int)n << " object(s) of size " << sizeof(T) << std::endl;
  51.         if (n == 0)
  52.             return NULL;
  53.         // All allocators should contain an integer overflow check.
  54.         // The Standardization Committee recommends that std::length_error
  55.         // be thrown in the case of integer overflow.
  56.         if (n > max_size())
  57.             throw std::length_error("pheap_allocator<T>::allocate() - Integer verflow.");
  58.         void * const pv = ::HeapAlloc(::GetProcessHeap(),HEAP_ZERO_MEMORY,n * sizeof(T));
  59.         // Allocators should throw std::bad_alloc in the case of memory allocation failure.
  60.         if (pv == NULL)
  61.             throw std::bad_alloc();
  62.         return static_cast<pointer>(pv);
  63.     }
  64.     void deallocate(T * const p, const size_t n) const
  65.     {
  66.         std::cout << "Deallocating " << (unsigned int)n << " object(s) of size " << sizeof(T) << std::endl;
  67.         ::HeapFree(::GetProcessHeap(),HEAP_ZERO_MEMORY,p);
  68.     }
  69.     //allocator::rebind 
  70.     //  A structure that enables an allocator for objects of one type to allocate storage for objects of another type
  71.     template <typename U>
  72.     struct rebind
  73.     {
  74.         typedef pheap_allocator<U> other;
  75.     };
  76.     // The following will be the same for all allocators that ignore hints.
  77.     template <typename U>
  78.     pointer allocate(const size_type n, const U * /* const hint */const
  79.     {
  80.         return allocate(n);
  81.     }
  82. private:
  83.     pheap_allocator& operator = (const pheap_allocator&);
  84. };
  85. // The definition of destroy() must be the same for all allocators.
  86. template <typename T>
  87. void pheap_allocator<T>::destroy(T * const p) const
  88. {
  89.     p->~T();
  90. };

//dll 内的导出函数fn2()

  1. #include <string>
  2. typedef std::basic_string<TCHAR, std::char_traits<TCHAR>, pheap_allocator<TCHAR> > tstring;
  3. #include <vector>
  4. typedef std::vector< tstring, pheap_allocator<tstring> > vecString;
  5. DLL_API int fn2(vecString &vs)
  6. {
  7.      vs.clear();
  8.      vs.push_back("1234567890123456789012345678901234567890");
  9.      vs.push_back("12345678901234567890");
  10.      vs.resize(5);
  11.      return 0;
  12. }

//测试

  1. DWORD WINAPI proc1(LPVOID)
  2. {
  3.     while(1)
  4.     {
  5.         tstring s = "12345678901234567890";
  6.         fn1(s);
  7.         s = "12345678901234567890123456789012345678901234567890123456789012345678901234567890";
  8.         vecString vs;
  9.         vs.push_back(s);
  10.         fn2(vs);
  11.         s = vs[0];
  12.         vs.clear();
  13.     }
  14.     return 0;
  15. }
  16. int _tmain(int argc, _TCHAR* argv[])
  17. {
  18.     for(int i = 0; i < 6; ++i)
  19.         CreateThread(NULL, 0, proc1, NULL, 0, NULL);
  20.     while(1){};
  21.     return 0;
  22. }

测试没有任何问题,代码用了进程的堆,HeapAlloc()的第二个参数里不加 HEAP_NO_SERIALIZE 标志的话,会自动对堆访问操作同步,多线程测试也通过

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值