Game programming essence 3 provides a stack distributor source code:
<Limits> <typename T> * T * & T & StackAlloc () * pStack, size_t nMaxBytes) StackAlloc & sa) _ MSC_VER >=1400 <typename U> StackAlloc <U> & sa) & = (StackAlloc & mpStack === *~ StackAlloc () pointer address (reference r) & std: numeric_limits <size_t>: max ()/(reinterpret_cast <*> (p)-> ~ Template <typename U> <U> pointer allocate (size_type n, * = * pRaw = mpStack ++ = (n * (mBytesAllocated +> deallocate (** reinterpret_cast <*> unsigned * GetStack () * template <typename T1 >=( StackAlloc <T1> & lhs, StackAlloc <T1> & rhs) lhs. getStack () = <typename T1>! = (StackAlloc <T1> & lhs, StackAlloc <T1> & rhs) lhs. GetStack ()! =View Code
The test showed that the stack Allocator was compiled and run under VS2012, and an error occurred while releasing the memory.
The reason is that when a user provides a custom distributor, VS will save an allocation policy object to manage the counting.
Some VS source code is as follows:
_ Alty & _ Al = typename _ Alloc: template rebind <_ Container_proxy>-> _ Myproxy = _ Alproxy. allocate (-> _ Myproxy-> _ Mycont =View Code
The stack Alval of vector is the stack Alval provided by the user.
The memory occupied by the allocation policy object _ Myproxy is also applied through _ Alval. However, the _ Myproxy is called by calling the template <typename U> StackAlloc (const StackAlloc <U> & sa) the rebinding function obtains a new Alproxy from _ Alval. In this case, _ Alval and _ Alproxy actually share a piece of memory, but they do not know each other's existence. This causes _ Myproxy to overwrite the element inserted by a vector. The program crashes when the memory of _ Myproxy needs to be released during vector release or memory migration.
In fact, the stack allocate provided by the essence of game programming has a semantic problem. mpstack should not be a value semantics, because the stack allocate actually does not actually apply for memory from the system, it does not actually release the memory, but only manages a memory segment that originally exists. Therefore, mpstack should reference semantics.
I will present the modified Code to you:
PS: the vector and list containers are tested only in VS2012.
Template <typename T> typedef T * typedef T & stack_alloc (), m_max_bytes (stack_alloc (uchar * pstack, size_t max_bytes) stack_alloc (stack_alloc & sa) _ MSC_VER> = 1400 template <typename U> stack_alloc (stack_alloc <U> & sa) stack_alloc & = (stack_alloc &*~ Stack_alloc () pointer address (reference r) & const_pointer address (const_reference c) & size_type max_size () m_max_bytes/(reinterpret_cast <*> (p)-> ~ Template <typename U> typedef stack_alloc <U> pointer allocate (size_type n, * = * praw = m_cur + = n * (m_cur +> m_begin + deallocate (** reinterpret_cast <*> unsigned * get_stack () uchar * & uchar * template <typename T >=( stack_alloc <T> & lhs, stack_alloc <T> & rhs) lhs. get_stack () = template <typename T>! = (Stack_alloc <T> & lhs, stack_alloc <T> & rhs) lhs. get_stack ()! =}View Code