C ++重载了新问题

时间:2012-08-01 18:48:01

标签: c++ overloading operator-keyword

我做了一个小机制来取代常规的new运算符。 基本上我们分配一个内存池(如16mb),当调用new时,返回 它的偏移量增长,直到没有更多的空间,我们再建一个池。一个游泳池 仅在释放该池中的所有元素时删除。

我已经测试了这个类,它的效果很好,比原来的新版快了大约8-15倍。 但是有一个问题:我将它合并到我的其他项目中,这个项目规模巨大 除了内存使用量增长非常快之外,它们正常工基本上没有释放池,因为 其中的一些项目根本不会被删除。此外,还有许多来自STL容器的new(0)调用 我不知道应该怎么回应。

以下是代码:

namespace rt
{
      class pool
      {
            friend class alloc;
            private:
                    unsigned int _numRecords;
                    unsigned int _sizeLeft;
                    char*        _ptr;
                    char*        _data;


      };


      class alloc
      {
            public:
                   alloc();

                   alloc(int mb);

                   ~alloc();

                   void* allocate(unsigned int size);

                   void constructPool(unsigned int idx);

                   void destroyPool(unsigned int idx);

                   void deallocate(void* ptr);

            private:
                    const static unsigned int           _numPools = 256;
                    const static unsigned int           _poolSize = 15*1024*1024;
                    const static unsigned int           _poolReplaceBound = 1*1024*1024; // if 1mb or less left we can replace it
                    pool*                               _pools[_numPools];
                    unsigned int                        _curPoolIdx;


      };          

这就是标题。 以下是实施:

namespace rt
{
          class pool
          {
                friend class alloc;
                private:
                        unsigned int _numRecords;
                        unsigned int _sizeLeft;
                        char*        _ptr;
                        char*        _data;

          };


      class alloc
      {
            public:
                   alloc();

                   alloc(int mb);

                   ~alloc();

                   void* allocate(unsigned int size);

                   void constructPool(unsigned int idx);

                   void destroyPool(unsigned int idx);

                   void deallocate(void* ptr);

            private:
                    const static unsigned int           _numPools = 256;
                    const static unsigned int           _poolSize = 15*1024*1024;
                    const static unsigned int           _poolReplaceBound = 1*1024*1024; // if 1mb or less left we can replace it
                    pool*                               _pools[_numPools];
                    unsigned int                        _curPoolIdx;


      };          

      extern alloc default_allocator;
}


#define RT_SAFE_MEM
namespace rt
{
      alloc default_allocator;


      alloc::alloc() 
      {
                     for(int i = 0; i < _numPools; i++) _pools[i] = NULL;
                     _curPoolIdx = 0;
                     constructPool(_curPoolIdx);
      }

      alloc::~alloc()
      {

      }

      void alloc::constructPool(unsigned int idx)
      {
                                    _pools[idx] = (pool*)malloc(sizeof(pool));
                                    _pools[idx]->_numRecords = 0;
                                    _pools[idx]->_sizeLeft = _poolSize;
                                    _pools[idx]->_data = (char*)calloc(_poolSize, 1);

                                    _pools[idx]->_ptr = _pools[idx]->_data; 
      }

      void alloc::destroyPool(unsigned int idx)
      {
           free(_pools[idx]->_data);
           free(_pools[idx]);
           _pools[idx] = NULL;
      }

      void* alloc::allocate(unsigned int size)
      {
            if(size == 0)
            {
                    return NULL;
            }
            #ifdef RT_SAFE_MEM

                                  if(size > _poolSize) 
                                  {
                                          MessageBox(NULL, "Allocation size exceeded maximum.", "Executor", MB_OK);
                                          return NULL;
                                  }
                                  if(*(_pools[_curPoolIdx]->_ptr) != 0)
                                  {
                                                                  //leak
                                                                  unsigned int leaksize = strlen(_pools[_curPoolIdx]->_ptr);
                                                                  char str[50];
                                                                  sprintf(str, "Memory corruption detected: wrote extra %u bytes. \nExporting to corrupt.txt", leaksize);
                                                                  FILE* fp = fopen("corrupt.txt", "w");
                                                                  fwrite(_pools[_curPoolIdx]->_ptr, 1, leaksize, fp);
                                                                  fclose(fp);
                                                                  MessageBox(NULL, str, "Executor", MB_OK);
                                                                  return NULL;
                                  }

            #endif

            if(_pools[_curPoolIdx]->_sizeLeft <= size)
            {
                                              //not enough size in this pool
                                              //make a new one
                                              _curPoolIdx++;
                                              //printf("expand");
                                              constructPool(_curPoolIdx);
                                              return allocate(size);

            }
            else
            {
                void* ans = (void*)_pools[_curPoolIdx]->_ptr;
                _pools[_curPoolIdx]->_ptr+=size;
                _pools[_curPoolIdx]->_sizeLeft-=size;
                _pools[_curPoolIdx]->_numRecords++;
                return ans;
            }
      }


      void alloc::deallocate(void* ptr)
      {
           for(int i = 0; i <= _curPoolIdx; i++)
           {
                   if(ptr >= _pools[i]->_data && ptr < _pools[i]->_ptr)
                   { 
                          //pool i contains this object
                          //printf("found %d\n", i); 
                          _pools[i]->_numRecords--;
                          if(_pools[i]->_numRecords == 0 && _pools[i]->_sizeLeft <= _poolReplaceBound)
                          {
                                                    //replace this pool
                                                    printf("replacing %d\n", i);
                                                    destroyPool(i);
                                                    if(_curPoolIdx == 0) constructPool(0);
                                                    else
                                                    {
                                                        for(int j = i; j < _numPools-1; j++)
                                                        {
                                                                _pools[j] = _pools[j+1];
                                                        } 
                                                        _curPoolIdx--;
                                                    }

                          }
                          return;
                   }
           }
           #ifdef RT_SAFE_MEM
                  char str[50];
                  sprintf(str,  "Attempted to deallocate foreign memory at 0x%.8X.", ptr);
                  MessageBox(NULL, str, "Executor", MB_OK);
           #endif
      }

}

如果有人看到错误或重大问题,请告诉我。 谢谢!

1 个答案:

答案 0 :(得分:2)

我建议您执行所有以下步骤:

  1. 编写测试程序以测试您的程序是否无错误运行或“有任何问题”
  2. 使用调试器查找错误,而不是SO的受众:-P
  3. 您应该记录代码所做的事情,而不是发布代码的完整列表,这将成为您未来的优秀参考点,并且将成为有用的文档(以及如何)你的代码