我使用兩個名爲IndexedHeap和HeapEntry的類實現了一個堆。我有一些損壞的內存訪問導致segfaults,我相信我知道在哪裏/爲什麼,但我不知道如何解決它。以下是我迄今爲止設計類的方法:C++雙向關聯內存管理策略
class IndexedHeap
{
private:
std::vector<HeapEntry*> heap; // the entries held by this heap
public:
...
};
class HeapEntry
{
private:
int index;
size_t priority;
unsigned long long key;
IndexedHeap* myHeap; // reference to heap where this entry resides
public:
HeapEntry(unsigned long long key, size_t priority, IndexedHeap* myHeap)
: key(key), priority(priority), index(-1), myHeap(myHeap)
{}
};
堆和它的條目都需要相互引用。正如你所看到的,我決定使用一個原始指針指向HeapEntry中的IndexedHeap。這是我認爲我出錯的地方,但我不確定。
在整個程序執行過程中,都會創建新的堆條目,作爲一堆的一部分。條目也從這堆中刪除並銷燬。也許當一個堆條目被銷燬時,它指向的堆被損壞。這將解釋我的內存問題,因爲下次堆入口嘗試訪問堆時,它將訪問已釋放的內存。
不幸的是,我並不相信這一點。我沒有實現HeapEntry的析構函數。默認的析構函數只是調用一個類的所有實例變量的析構函數?那麼指向myHeap的指針會不會被破壞,而堆對象本身還能存活?
那麼,設計這種關係的正確方法是什麼?我的記憶問題可以從我發佈的代碼中解釋出來嗎?謝謝,請讓我知道你是否想看更多的代碼或更多的細節。
HeapEntry* IndexedHeap::insert(unsigned long long key)
{
HeapEntry* entry = new HeapEntry(key, 1, this);
heap.push_back(entry);
int index = heapifyUp(heap.size() - 1);
heap[index]->setIndex(index);
return entry;
}
void IndexedHeap::deleteAtIndex(int pos)
{
if (pos >= 0 && pos < heap.size())
{
// Copy heap.back() into the position of target, thus overwriting it
*heap[pos] = *heap.back();
// Fix the index field for the just copied element
heap[pos]->setIndex(pos);
// We've removed the target by overwriting it with heap.back()
// Now get rid the extra copy of heap.back()
// Release the mem, then pop back to get rid of the pointer
delete heap.back();
heap.pop_back();
// Heapify from the position we just messed with
// use heapifyDown because back() always has a lower priority than the element we are removing
heapifyDown(pos);
}
}
HePentry是如何得到分配的,它應該如何被釋放?你如何確保沒有人擁有已釋放HeapEntry的丹靈指針?如果STL容器涉及釋放指針,則在STL容器類中使用普通舊指針是一個確定的內存損壞票據。你應該去看看智能指針。 –
那麼,爲什麼你不使用STL的優先級隊列,或者使用multimap作爲優先級隊列?它比編寫自己的解決方案更好。 – RichardPlunkett
我對智能指針不太熟悉,所以我一定會閱讀它們並嘗試查看它們可以提供的幫助。我現在還要編輯這個問題,以包含創建和銷燬堆條目的代碼。 – yan