簡體   English   中英

C ++刪除指針

[英]C++ Deleting pointer

我正在編寫一個使用指針和非指向項的結構的程序,我試圖適當地分配數據以減少開銷(這確實很重要)。

這就是我所擁有的。 我本質上是在為自己的隊列添加特定功能。 我的結構僅包含一條通用數據和指向下一個位置的指針引用。

template<class T>
struct Spot
{
    T data;
    Spot *spotBehind;
};

當我添加一個新的Element時 ,我將使用以下代碼進行操作(跟蹤隊列的頭和尾)。

if(front == NULL)           //Make first head
    {
        Spot<T> *newSpot = new Spot<T>();
        newSpot->data = newElement;
        newSpot->spotBehind = front;
        front = newSpot;
        back = front;
    }
    else        //Find back of line and add
    {
        Spot<T> *newSpot = new Spot<T>();
        newSpot->data = newElement;
        newSpot->spotBehind = NULL;
        back->spotBehind = newSpot;
        back = newSpot;
    }

因此,在此之后,當涉及到析構函數時,我當然需要對我擁有的每個新對象都進行刪除 所以我的析構函數使用以下代碼:

Spot<T> *current = front;
Spot<T> *next = NULL;
while(current != NULL)
{
    next = current->spotBehind;

    delete current;
    current = NULL;

    current = next;
}

現在我的關注就在這里。 當我使用析構函數時,我不認為它在做應有的工作,並且這里可能存在內存泄漏。 通過各種cout語句,我可以驗證我的信息是否已存儲並按預期工作。 但是,當我刪除數據時,它實際上似乎並沒有被刪除。 為了嘗試對其進行調試,我用以下代碼替換了重構器代碼(上文),以了解其功能。

while(current != NULL)
{
    next = current->spotBehind;

    cout << "Before Delete " << current << " Data: " << current->data << endl;
    delete current;
    cout << "After Delete " << current << " Data: " << current->data << endl;
    current = NULL;
    cout << "After Null " << current << endl;
    current = next;
    if(current != NULL)
        cout << "After Reassigned " << current << " Data: " << current->data << endl;
}

我得到以下結果:

Before Delete 0x100103b20 Data: 5
After Delete 0x100103b20 Data: 5
After Null 0x0
After Reassigned 0x100103b30 Data: 10
Before Delete 0x100103b30 Data: 10
After Delete 0x100103b30 Data: 10
After Null 0x0

如此大的問題

所以我的大問題是,信息實際上是按照應該的方式重新分配的。 我以為我做錯了,因為在Spot指針上使用'delete'命令后,之后仍然可以看到該值(以及spotBehind指針)。 如果它按照我想要的方式工作,我應該不是應該看到垃圾值和空的spotBehind指針,還是不能訪問數據? 我會很高興有人向我解釋這一點,如果我做錯了,有人可以建議一種正確刪除信息的方法嗎?

我認為您的代碼按預期工作。

確定刪除后數據仍然存在,因為刪除並不意味着必須將其覆蓋。 delete僅告訴內存管理該指針指向的內存將不再使用,可以重新分配。 在該操作之后對其進行訪問是非法的,並且可能會導致未定義的行為,但是大多數情況下都可能會發生任何訪問沖突,因為該地址仍指向應用程序堆。

內存分配通常通過一種鏈表來實現。 自由操作會將塊標記為對系統可用。 通常,釋放的內存將取決於編譯器和構建的類型-您是否在Debug of Release中打印了這些值?

例如,處於調試模式的MS編譯器通過以下方式填充釋放的塊:

memset(pHead, _bDeadLandFill,  // 0xdddddddd

這里0xdddddddd是編譯器用來標記釋放的內存的特殊值。

並嘗試打印已刪除指針的數據會導致Access violation錯誤。 您可以嘗試調試operator delete以查看如何在系統中實現它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM