Note that there are some explanatory texts on larger screens.

plurals
  1. POC++ overloaded new issue
    text
    copied!<p>I have made a small mechanism that replaces the regular new operator. Basically we allocate a pool of memory (like 16mb) and when new is called, return an offset to it that grows until there is no more room and we make another pool. A pool is deleted only when all of the elements in that pool are freed.</p> <p>I have tested this class and it works great and around 8-15 times faster than the original new. There is a problem however: I incorporated it into my other project which is huge in size, it works normally except the memory usage grows very quickly. Basically the pools aren't freed because some items in them are not deleted at all. Also, there are many calls to new(0) from STL containers to which I dont know how should it respond. </p> <p>Here is the code:</p> <pre><code>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; }; </code></pre> <p>That was the header. Here is the implementation:</p> <pre><code>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 &lt; _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]-&gt;_numRecords = 0; _pools[idx]-&gt;_sizeLeft = _poolSize; _pools[idx]-&gt;_data = (char*)calloc(_poolSize, 1); _pools[idx]-&gt;_ptr = _pools[idx]-&gt;_data; } void alloc::destroyPool(unsigned int idx) { free(_pools[idx]-&gt;_data); free(_pools[idx]); _pools[idx] = NULL; } void* alloc::allocate(unsigned int size) { if(size == 0) { return NULL; } #ifdef RT_SAFE_MEM if(size &gt; _poolSize) { MessageBox(NULL, "Allocation size exceeded maximum.", "Executor", MB_OK); return NULL; } if(*(_pools[_curPoolIdx]-&gt;_ptr) != 0) { //leak unsigned int leaksize = strlen(_pools[_curPoolIdx]-&gt;_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]-&gt;_ptr, 1, leaksize, fp); fclose(fp); MessageBox(NULL, str, "Executor", MB_OK); return NULL; } #endif if(_pools[_curPoolIdx]-&gt;_sizeLeft &lt;= 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]-&gt;_ptr; _pools[_curPoolIdx]-&gt;_ptr+=size; _pools[_curPoolIdx]-&gt;_sizeLeft-=size; _pools[_curPoolIdx]-&gt;_numRecords++; return ans; } } void alloc::deallocate(void* ptr) { for(int i = 0; i &lt;= _curPoolIdx; i++) { if(ptr &gt;= _pools[i]-&gt;_data &amp;&amp; ptr &lt; _pools[i]-&gt;_ptr) { //pool i contains this object //printf("found %d\n", i); _pools[i]-&gt;_numRecords--; if(_pools[i]-&gt;_numRecords == 0 &amp;&amp; _pools[i]-&gt;_sizeLeft &lt;= _poolReplaceBound) { //replace this pool printf("replacing %d\n", i); destroyPool(i); if(_curPoolIdx == 0) constructPool(0); else { for(int j = i; j &lt; _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 } </code></pre> <p>}</p> <p>If anyone sees a bug or a major problem, let me know. Thanks!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload