STL 的自定义分配器仅在发布模式下无法编译

Custom allocator for STL fails to compile in release mode only

我写了一个自定义分配,我正在使用 std::vector。代码在调试模式下编译并工作,但在发布模式下编译失败并出现奇怪错误。

这是我的分配器:

template< class T >
class AllocPowOf2
{
public:

   typedef size_t     size_type;
   typedef ptrdiff_t  difference_type;
   typedef T *        pointer;
   typedef const T *  const_pointer;
   typedef T &        reference;
   typedef const T &  const_reference;
   typedef T          value_type;

private:

   size_type m_nMinNbBytes;

public:

   template< class U >
   struct rebind
   {
       typedef AllocPowOf2< U > other;
   };

   inline pointer address( reference value ) const
   {
       return & value;
   }

   inline const_pointer address( const_reference value ) const
   {
       return & value;
   }

   inline AllocPowOf2( size_type nMinNbBytes = 32 )
    : m_nMinNbBytes( nMinNbBytes ) { }

   inline AllocPowOf2( const AllocPowOf2 & oAlloc )
    : m_nMinNbBytes( oAlloc.m_nMinNbBytes ) { }

   template< class U >
   inline AllocPowOf2( const AllocPowOf2< U > & oAlloc )
    : m_nMinNbBytes( oAlloc.m_nMinNbBytes ) { }

   inline ~AllocPowOf2() { }

   inline bool operator != ( const AllocPowOf2< T > & oAlloc )
   {
      return m_nMinNbBytes != oAlloc.m_nMinNbBytes;
   }

   inline size_type max_size() const
   {
       return size_type( -1 ) / sizeof( value_type );
   }

   static size_type OptimizeNbBytes( size_type nNbBytes, size_type nMin )
   {
      if( nNbBytes < nMin )
      {
         nNbBytes = nMin;
      }
      else
      {
         size_type j = nNbBytes;

         j |= (j >>  1);
         j |= (j >>  2);
         j |= (j >>  4);
         j |= (j >>  8);

#if ENV_32BITS || ENV_64BITS
         j |= (j >> 16);
#endif
#if ENV_64BITS
         j |= (j >> 32);
#endif
         ++j; // Least power of two greater than nNbBytes and nMin

         if( j > nNbBytes )
         {
            nNbBytes = j;
         }
      }
      return nNbBytes;
   }

   pointer allocate( size_type nNum )
   {
      return new value_type[ OptimizeNbBytes( nNum * sizeof( value_type ), 32 ) ]; // ERROR HERE, line 97
   }

   void construct( pointer p, const value_type & value )
   {
      new ((void *) p) value_type( value );
   }

   void destroy( pointer p )
   {
      p->~T();
   }

   void deallocate( pointer p, size_type nNum )
   {
      (void) nNum;
      delete[] p;
   }
};

这是错误:

Error   1   error C2512: 'std::_Aux_cont' : no appropriate default constructor available    c:\XXX\AllocPowOf2.h    97

代码在 Windows 使用 VS2008 和 Android 使用 Android NDK 和 eclipse 时都可以在调试模式下正确编译。

有什么想法吗?

return new value_type[ OptimizeNbBytes( nNum * sizeof( value_type ), 32 ) ];

暂时忽略 OptimizeNbBytes,您正在 new 调用 nNum * sizeof(value_type) value_types,它也多次调用 value_type 的构造函数。

换句话说,要求分配 16 int 秒的内存,你会分配足够的 64 int 秒;不仅如此,你还被要求提供原始内存,而不是 运行 构造函数,创建将被容器覆盖而不被销毁的对象 - 然后 delete[] in deallocate会造成双重破坏

allocate 应分配原始内存:

return pointer(::operator new(OptimizeNbBytes( nNum * sizeof( value_type ), 32 )));

deallocate 应该在没有 运行 任何析构函数的情况下释放内存:

::operator delete((void*)p);