我正在處理運行時new
在程序仍然需要內存時的失敗。我不想讓程序停下來。那麼無論如何要重新分配?提前致謝!新的和malloc(C++)未能分配內存。如何修復/重新分配?
回答
你可以就在年初
FixedMemory<1024> fMem(4); // memsize 1024Char
FixedHeap<1024,16> fHeap(fMem); // 1KiB/ 16Byte = 64 Blocks
// if usual allocation fails:
ptr = (ptrdiff_t) fHeap.alloc(16);// sizeof(Foo)
Foo* foo = new (ptr) Foo();
// make sure that Foo does not call new/malloc/...
// or you have to handle that as well
foo->~Foo;
fHeap.free(pMem);
當然預留用於緊急用途的大型靜態存儲器塊,那麼你必須實現自己的內存管理。你寫你自己的堆類如下界面:
class Heap {
protected:
/** Initializes reference to system memory.*/
Heap(Memory& memory) : memory(memory)
{
}
public:
/** Allocate a piece of memory.
* @param size size of the memory to allocate
* @return pointer to allocated memory or null on error
*/
virtual void* alloc(size_t size)=0;
/** Free previously allocated memory.
* @param p pointer to the memory to free
*/
virtual void free(void* address)=0;
private:
/** Reference to the system memory source. */
Memory& memory;
};
最簡單的實現將是一個固定堆,只返回一個固定長度的指針segmens(或空指針,如果你試圖獲得更多)。這是可以的,如果你已經知道你需要分配的最大尺寸(sizeof(ClassToWorkWith)
)。
然後您需要固定的內存:
template<size_t MEMSIZE>
class FixedMemory {
private:
char MemArray[MEMSIZE];
const size_t alignment;
public:
FixedMemory(size_t alignment) : alignment(alignment)
{
}
void * GetMemory()
{
return (void*)((char*)MemArray);
}
};
然後你就可以實現一個固定堆基本上是這樣的
template<size_t MEMSIZE, size_t BLOCKSIZE>
class FixedHeap : public Heap {
private:
void *FreeHead;
size_t realBlockSize;
public:
FixedHeap(Memory& memory) : Heap(memory), FreeHead(0)
{
realBlockSize = BLOCKSIZE;
if(memory.alignment < sizeof(void*))return;
if(realBlockSize < sizeof(void*))realBlockSize = sizeof(void*);
realBlockSize += (BLOCKSIZE%memory.alignment) ? (memory.alignment - BLOCKSIZE%memory.alignment) : 0;
if(MEMSIZE >= realBlockSize) {
char *pMemory = (char *)memory.GetMemory();
size_t malAlignment = (memory.alignment - (size_t)pMemory%memory.alignment)%memory.alignment;
size_t actualMemSize = MEMSIZE - malAlignment;
pMemory += malAlignment;
for(size_t i=0; i<actualMemSize/realBlockSize-1; i++)
{
*((ptrdiff_t *)(&pMemory[i*realBlockSize])) = (ptrdiff_t)&pMemory[(i+1)*realBlockSize];
}
*((ptrdiff_t *)(&pMemory[(actualMemSize/realBlockSize-1)*realBlockSize])) = 0;
FreeHead = (void *)pMemory;
}
}
void* alloc(size_t size)
{
if(size > BLOCKSIZE || !FreeHead) return 0;
void *Result = FreeHead;
FreeHead = (void *)*((ptrdiff_t *)FreeHead);
return Result;
}
void free(void* address)
{
if(address && (! address % realBlockSize)) {
*((ptrdiff_t *)address) = (ptrdiff_t)FreeHead;
FreeHead = address;
}
}
};
有一些更好的替代品,像FirstFitHeap
但我只是想給你一個提示。
你能解釋一下嗎? – user699673 2011-04-09 06:05:38
您可以在不需要時暫時將對象存儲到磁盤,並在需要訪問它們時重新加載它們。例如Photoshop曾經擁有它自己的交換文件IIRC。但是,滾動你自己的基於文件的對象存儲並不容易 - 不確定是否有適當的實現已經存在。
另一方面,在你問這個問題的方式中,你似乎意外地耗盡了內存 - 所以你可能已經在你的應用程序設計中遇到了某種問題,並試圖修復症狀而不是原因不是必然是最好的行動方針。
請提供更多詳情。
從你給出的描述中,我假設你的程序會拋出內存分配錯誤。 按照這種模式,至少在內存不足情況下能夠正常退出。
在程序開始之前保留一些內存。 炭reserveMemory =新的char [1024 * 1024] // 1Mb的
寫一個函數在內存不足的情況下,解除該存儲器,並將其設置爲new_handler(檢查set_new_handler()是一個好的C++書)。
在您釋放reserveMemory之後,您的堆上有1 MB的內存。這取決於你的技能,利用這個內存退出,或通過釋放堆中的不需要的對象等來恢復更多內存。
作爲評論會更好。 – dmckee 2011-04-09 18:57:18
- 1. 內存分配/重新分配問題
- 2. 如何分配和重新分配內存?
- 3. malloc分配內存和SIGSEGV
- 4. malloc內存分配
- 5. 重複調用glBufferData未能爲新緩衝區分配內存
- 6. 重新分配C++數組的內存。
- 7. 內存重新分配使用的std ::矢量重新分配
- 8. 內存重新分配
- 9. 內存不重新分配
- 10. C++類數組內存重新分配
- 11. 在C中重新分配內存
- 12. malloc觸摸未分配的內存
- 13. 動態分配和重新分配樹中的內存算法
- 14. Renderscript中的內存分配和重新分配
- 15. C++內存分配新[]和刪除[]
- 16. C中的malloc內存分配方案
- 17. C++新操作符分配新內存
- 18. 取消分配和重新分配內存。在FLTK
- 19. 使用malloc()分配內存
- 20. 如何檢查內存是否使用malloc或新分配
- 21. 不能釋放C中的重新分配內存
- 22. Malloc和新運算符分配內存有什麼區別?
- 23. Golang新的內存分配
- 24. 新的不分配內存
- 25. 新的內存分配
- 26. 讀取功能:複製緩衝區,重新分配內存
- 27. 未能分配內存android
- 28. Android:未能分配內存
- 29. C++新的內存分配碎片
- 30. 如何重新分配的值在C++
你能解釋得更好嗎? – 2011-04-09 05:58:41
你的程序真的需要比你的機器上更多的內存嗎?如果確實如此,那麼如果你無法獲得更多的信息,那麼很難繼續,如果它實際上並不需要它,也許你實際上並不需要遇到'new'的失敗。 – Cascabel 2011-04-09 06:08:21
這取決於你需要多少額外的內存(會有固定的數量嗎?),以及是否有可能釋放任何現有的分配。這種情況並不常見,因爲大多數現代操作系統會過度使用內存,這通常會導致系統逐漸放緩,甚至在發生'throw bad_alloc'之前崩潰。 – Potatoswatter 2011-04-09 06:09:56