none
用allocator类重载operator new/delete 问题? RRS feed

  • 问题

  • 一项目中需要频繁new delete某个类,于是我想提高效率,选用合适的allocator,如std::allocator, boost::allocator 通过重载operator new / delete做具体的内存分配/释放操作。

    于是我写了如下测试代码:

    #include <cstdio>
    #include <cstdlib>
    #include <memory>
    
    struct Test {
         static std::allocator<Test> alloc;
    
         void *operator new( size_t size )
         {
              printf( "Test::new() size = %u\n", size );
              return alloc.allocate(1);
         }
        
         void operator delete( void *ptr, size_t size )
         {
              printf( "Test::delete() size = %u, ptr = %x\n", size, ptr );
              alloc.deallocate((Test*)ptr, 1);
         }
        
         void *operator new[] ( size_t size )
         {
              printf( "Test::new()[] size = %u\n", size );
              return alloc.allocate( size / sizeof(Test) );        
         }
        
         void operator delete[]( void *ptr, size_t size )
         {
              printf( "Test::delete()[] size = %u, ptr = %x\n", size, ptr );
    		  alloc.deallocate( (Test*)ptr, size / sizeof(Test) );
         }    
        
         int x, y;
    };
    
    std::allocator<Test> Test::alloc;
    
    int main()
    {
    	 // test 1
         {
              Test *p = new Test;
              printf( "p = %x\n", p );
              delete p;
         }
        
         getchar();
    
        // test 2
         {
              Test *p = new Test[10];
              printf( "p = %x\n", p );
              delete [] p;    
         }
        
         return 0;
    }
    

    第一个测试用例,测试new单个对象,没什么问题。

    但是!!!第二个测试,数组版的,用vs2008编译运行结果如下:

    Test::new()[] size = 80
    p = 425e80
    Test::delete()[] size = 8, ptr = 425e80
    

    new[]来的指针和delete[]传入指针一样,new[]传入的size参数是整个数组大小,以此确定allocator::allocate()函数count参数,但delete[]函数传入size参数却是一个元素大小而不是整个数组大小,无法用来确定allocator::deallocate()函数count参数。

    用g++在Linux环境下运行,结果却是这样的:

    Test::new()[] size = 84
    p = 9b0401c // p 指向分配来的数组
    Test::delete()[] size = 84, ptr = 9b04018 // ptr为传入delete[]的指针,比p前移4字节
    

    new[] delete[]传入的size参数都比预期的多了4字节,即delete[]传入的ptr指针比数组实际地址向前偏移了4字节,经调试发现多出的4字节用以存储数组大小。

    这是什么原因?

    解决频繁new delete还有没有更好的方法?

    2013年6月14日 10:17

全部回复