Chapter 2-01

Please indicate the source: http://blog.csdn.net/gaoxiangnumber1

Welcome to my github: https://github.com/gaoxiangnumber1

2.1 空间配置器的标准接口

根据 STL 的规范,以下是 allocator 的必要界面: P74

2.1.1 设计一个阳春的空间配置器, JJ::allocator

test_alloc.h

code

review

#ifndef TESTALLOC_H

#define TESTALLOC_H

 

#include<cstddef>  // for ptrdiff_t

#include<cstdlib>  // for exit()

#include<climits>  // for UINT_MAX

#include<iostream>  // for cerr

 

namespace TestAlloc

{

template<class T>

inline T* _allocate(ptrdiff_t size, T*)

{

      std::set_new_handler(0);  // must add "std::"

      T* pointer = (T*)(::operator new((size_t)(size * sizeof(T))));

      if(pointer == 0)  // memory allocation failure

      {

           std::cerr << "No memory\n";  // must add "std::"

           exit(1);

      }

      return pointer;

}

 

template<class T>

inline void _deallocate(T *buffer)

{

      ::operator delete(buffer);

}

 

template<class T1, class T2>

inline void _construct(T1 *p, const T2 &value)

{

      new (p) T1(value);  // placement new

}

 

template<class T>

inline void _destroy(T *pointer)

{

      pointer->~T();

}

 

template<class T>

class Allocator

{

public:

      typedef                           T         value_type;

      typedef                           T* pointer;

      typedef         const   T* const_pointer;

      typedef                           T&      reference;

      typedef             const     T&      const_reference;

      typedef                      size_t  size_type;

      typedef                ptrdiff_t   difference_type;

 

      // rebind allocator of type U

      template<class U>

      struct rebind

      {

           typedef Allocator<U> other;

      };

 

      pointer allocate(size_type n, const void *hint = 0)

      {

           return _allocate((difference_type)n, (pointer)0);

      }

 

      void deallocate(pointer p, size_type n)

      {

           _deallocate(p);

      }

 

      void construct(pointer p, const T &value)

      {

           _construct(p, value);

      }

 

      void destroy(pointer p)

      {

           _destroy(p);

      }

 

      pointer address(reference x)

      {

           return (pointer)&x;

      }

 

      const_pointer const_address(const_reference x)

      {

           return (const_pointer)&x;

      }

 

      size_type max_size() const

      {

           return size_type(UINT_MAX / sizeof(T));  // in climits: #define UINT_MAX 0xffffffff

      }

};

}

 

#endif // TESTALLOC_H

test_alloc.cc

code

review

#include "test_alloc.h"

#include<iostream>

#include<vector>

using namespace std;

 

int main()

{

      int num[5] = {0, 1, 2, 3, 4};

      vector<int, TestAlloc::Allocator<int> > vec(num, num + 5);

 

      for(int i = 0; i < 5; i++)

      {

           cout << vec[i] << ' ';

      }

      cout << endl;

 

      return 0;

}

 

Reference:

ptrdiff_t

l  #include<cstddef>

l  Result of pointer subtraction. Alias of one of signed integer types. A pointer subtraction is only guaranteed to have a valid defined value for pointers to elements of the same array (or for the element just past the last in the array).

std::new_handler

l  #include<new>

l  typedef void (*new_handler)();

l  new_handler is a function pointer type for functions that take no arguments and return no value. It is used as the argument and return type in function set_new_handler.

l  A new-handler function is called by the standard definition of functions operator new and operator new[] when they fail to allocate memory.

std::set_new_handler

l  #include<new>

l  C++11: new_handler set_new_handler (new_handler new_p) noexcept; Sets new_p as the new-handler function.

l  The new-handler function may try to make more storage available for a new attempt to allocate the storage. If and only if the function succeeds in making more storage available, it may return. Otherwise it shall either throw a bad_alloc exception (or a derived class) or terminate the program (such as by calling abort or exit).

l  If the new-handler function returns (i.e., it made more storage available), it may be called repeatedly for as long as the allocation function fails to allocate the requested storage, or until the new-handler function does not return or is replaced.

l  Before this function is called by the program for the first time, or if new_p is a null-pointer, the default allocation functions directly throw bad_alloc on failure.

l  Parameters: new_p is a function that takes no arguments and returns no value (void). The function can make more storage available, or throw an exception, or terminate the program. If this is a null-pointer, the new-handler function is reset to none (and bad_alloc is thrown instead).

l  Return value: The value of the current new-handler function if this has already been set by this function previously, or a null-pointer if this is the first call to set_new_handler (or if it was reset by a previous call).

l  Code:

#include<iostream>

#include<cstdlib>  // use exit

#include<new>  // use set_new_handler

using namespace std;

 

void no_memory()

{

      cout << "No Memory\n";

      exit(1);  // if we not use or omit "exit()", then this program will not stop.

}

 

int main()

{

      set_new_handler(no_memory);

      cout << "Attempt to allocate LARGE memory\n";

      double *p = new double[1 << 31];

// output "No Memory", if new double [1]: OK

      cout << "OK\n";

      delete [] p;

 

      return 0;

}

operator new

l  #include<new>

l  void* operator new (std::size_t size);
This is the default allocation function (single-object form).

l  Allocates size bytes of storage, suitably aligned to represent any object of that size, and returns a non-null pointer to the first byte of this block. On failure, it throws a bad_alloc exception.

l  Parameter: size
Size in bytes of the requested memory block. This is the size of the type specifier in the new-expression when called automatically by such an expression. If this argument is zero, the function still returns a distinct non-null pointer on success (although dereferencing this pointer leads to undefined behavior). size_t is an integral type.

l  Return value: A pointer to the newly allocated storage space.

Please indicate the source: http://blog.csdn.net/gaoxiangnumber1

Welcome to my github: https://github.com/gaoxiangnumber1

你可能感兴趣的:(Chapter 2-01)