自定义分配器编译困难2

时间:2014-06-29 21:04:40

标签: c++ c++11 allocator

我正在定义一个自定义分配器,但我需要将分配器的指针保留为偏移量。当我将指针定义更改为" size_t"键入代码不会再次编译,没有明显的线索! 需要创建一个自定义分配器,其中内存在"段中进行寻址:偏移"样式和段(对象)的地址是可重定位的。

#include <bits/c++config.h>
#define _GLIBCXX_FULLY_DYNAMIC_STRING 0

#include <stdint.h>
#include <stddef.h>

#include <memory>
#include <string>
#include <limits>


typedef int32_t Token;
typedef unsigned char byte;

using namespace std;
template <typename T>
struct Allocator {
 public:

// http://www.codeproject.com/Articles/4795/C-Standard-Allocator-An-Introduction-and-Implement

    typedef T value_type;

    typedef std::size_t pointer;
    typedef const std::size_t const_pointer;


    typedef value_type& reference;typedef const value_type& const_reference;

    typedef std::size_t size_type;
  typedef std::ptrdiff_t difference_type;

  template<typename U> struct rebind {typedef Allocator<U> other;};

    static const size_t heapSize=0x1000;
    static pointer freePos;
    static Token freeT;
    static byte m[heapSize];

    inline explicit Allocator() {freeT=0;freePos=0;}
  inline ~Allocator() {}
  inline Allocator(Allocator const&) {} // with explicit it doesn't compile

  inline pointer address(reference r) {return &r;}
  inline const_pointer address(const_reference r) {return &r;}

  //static inline pointer allocate(size_type n, typename std::allocator<void>::const_pointer hint = 0){ 
    //  pointer t=freePos;freePos+=n*sizeof(T);return t;
  static inline pointer allocate(size_type n){pointer t=freePos;freePos+=n*sizeof(T);return t;}


    static void deallocate(pointer p, size_type n){
    *(pointer*)((byte*)m+p)=(pointer)(n*sizeof(T));
    }

    static inline void deallocate(T* p,size_type n){deallocate((pointer)((byte*)p-m),n);}
    static inline void deallocate(const T* p,size_type n){deallocate((pointer)((byte*)p-m),n);}

  inline size_type max_size() const{ 
        return std::numeric_limits<size_type>::max() / sizeof(T);
    }
  inline void construct(pointer p, const T& t) {}
  inline void destroy(pointer p) {}

};

template <typename T>
bool operator==(Allocator<T> const &, Allocator<T> const &) { return true; }

template <typename T>
bool operator!=(Allocator<T> const &, Allocator<T> const &) { return false; }


using namespace std;

typedef     std::basic_string< char,std::char_traits<char>,Allocator<char> > String;

int main(){
String s("nice");
String t("very nice");
String u("good");
return 0;
}

1 个答案:

答案 0 :(得分:1)

保持pointerconst_pointer的定义与标准库期望的方式相同:

  typedef T* pointer;
  typedef const T* const_pointer;

添加新的typedef

  typedef std::size_t offset_type;

在合适的地方使用offset_type代替pointer

这是一个编译和构建但在运行时生成Segmentation Fault的版本。我会留给你找出那个问题。

#include <bits/c++config.h>
#define _GLIBCXX_FULLY_DYNAMIC_STRING 0

#include <stdint.h>
#include <stddef.h>

#include <memory>
#include <string>
#include <limits>


typedef int32_t Token;
typedef unsigned char byte;

using namespace std;
template <typename T>
struct Allocator {
   public:

      // http://www.codeproject.com/Articles/4795/C-Standard-Allocator-An-Introduction-and-Implement

      typedef T value_type;

      typedef T* pointer;
      typedef const T* const_pointer;

      typedef std::size_t offset_type;


      typedef value_type& reference;typedef const value_type& const_reference;

      typedef std::size_t size_type;
      typedef std::ptrdiff_t difference_type;

      template<typename U> struct rebind {typedef Allocator<U> other;};

      static const size_t heapSize=0x1000;
      static offset_type freePos;
      static Token freeT;
      static byte m[heapSize];

      inline explicit Allocator() {freeT=0;freePos=0;}
      inline ~Allocator() {}
      inline Allocator(Allocator const&) {} // with explicit it doesn't compile

      inline offset_type address(reference r) {return &r;}
      inline const_pointer address(const_reference r) {return &r;}

      //static inline offset_type allocate(size_type n, typename std::allocator<void>::const_pointer hint = 0)
      //  offset_type t=freePos;freePos+=n*sizeof(T);return t;
      static inline pointer allocate(size_type n){offset_type t=freePos;freePos+=n*sizeof(T);return (pointer)t;}


      static void deallocate(offset_type p, size_type n){
         *(offset_type*)((byte*)m+p)=(offset_type)(n*sizeof(T));
      }

      static inline void deallocate(pointer p,size_type n){deallocate((offset_type)((byte*)p-m),n);}
      static inline void deallocate(const_pointer* p,size_type n){deallocate((offset_type)((byte*)p-m),n);}

      inline size_type max_size() const{ 
         return std::numeric_limits<size_type>::max() / sizeof(T);
      }
      inline void construct(offset_type p, const T& t) {}
      inline void destroy(offset_type p) {}

};

template <typename T>
typename Allocator<T>::offset_type Allocator<T>::freePos;

template <typename T>
Token Allocator<T>::freeT;

template <typename T>
byte Allocator<T>::m[Allocator::heapSize];

template <typename T>
bool operator==(Allocator<T> const &, Allocator<T> const &) { return true; }

template <typename T>
bool operator!=(Allocator<T> const &, Allocator<T> const &) { return false; }


using namespace std;

typedef     std::basic_string< char,std::char_traits<char>,Allocator<char> > String;

int main(){
   String s("nice");
   String t("very nice");
   String u("good");
   return 0;
}