簡體   English   中英

c ++刪除不存在的指針

[英]c++ deleting non-existing pointers

class C {

public:
    std::vector<C*> list;
    int value;

    C(int value,  C* parent)
    {
        this->value = value;

        if(parent)
        {
            parent->registerChild(this);
        }
    }

    void registerChild(C* child)
    {
        this->list.push_back(child);
    }

    ~C()
    {
        for(std::vector<C*>::iterator it = list.begin(); it != list.end(); ++it)
        {
            if( (*it))
            {
                delete (*it);
            }
        }
    }
};

這是一個GUI項目。 具有父級的子類必須通知它的父類,以便在刪除父類時,也應刪除其所有子級。

C* main = new C(100, 0);

C* child1 = new C(250, main);
C* child2 = new C(450, main);

delete main;

^一切按預期工作 - main與child1和child2一起刪除。

C* main = new C(100, 0);

C* child1 = new C(250, main);
C* child2 = new C(450, main);

delete child1;

delete main; // windows error

如果我決定首先擺脫child1,然后稍后決定刪除main,我會得到一個Windows錯誤,可以追溯到矢量循環,顯然刪除嘗試刪除現在不存在的指針。 我原以為if((* it))會為不再存在的指針返回false。

我能在這做什么?

編輯:這似乎完美無缺

class C {

    typedef std::vector<C*> cList;

public:
    std::vector<C*> list;
    int value;
    C* parent;

    C(int value,  C* parent)
    {
        this->value = value;
        this->parent = parent;

        if(parent)
        {
            parent->registerChild(this);
        }
    }

    void registerChild(C* child)
    {
        this->list.push_back(child);
    }

    void removeChild(C* child)
    {
        cList::iterator it = std::find(list.begin(), list.end(), child);

        if(it != list.end())
        {
            list.erase(it);
        }
    }

    ~C()
    {
        if(this->parent)
        {
            // this child is being removed - notify parent and remove this from its child_list
            this->parent->removeChild(this);
        }

        cList::iterator it = list.begin();

        while(it != list.end())
        {
            delete (*it);

            // find a new beginning
            it = list.begin();
        };
    }
};

當你調用delete main ,它會在其子delete上調用delete child1就是其中之一。 所以你在同一個內存地址上調用delete兩次。 這是未定義的行為

我原以為if( (*it))會為不再存在的指針返回false。

不,沒有機制讓一個指針知道它指向的對象已經通過另一個指針刪除了。

我能在這做什么?

確保只有一個實體負責管理動態分配的對象。

這是一個半廣泛的錯誤概念,當指針被指向的內存被刪除時,指針被設置為NULL。 它不是。 此外,刪除NULL是安全的,因此在刪除指針之前檢查指針是否為NULL是不必要的(關閉主題...)。

指針沒有什么神奇之處。 它們(通常是)機器字寬的整數,可用於指代特定的存儲器地址。 當它提到的內存區域不再由您的程序擁有時,沒有任何魔法可以使整數為NULL。

處理像這樣的原始指針是一個壞主意。 人們很容易被誰負責管理指向的內存所迷惑。

查看std :: unique_ptr和std :: shared_ptr( http://en.cppreference.com/w/cpp/memory )。

考慮將父指針保持為類的成員,添加注銷成員函數。 然后在類的析構函數中,讓對象從父對象中取消注冊。 您需要更改管理子窗口列表的方式。

此外,類成員變量的名稱實際上應該更具描述性。 list並沒有告訴我們多少。 考慮像childrenchild_list這樣的名稱。

暫無
暫無

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

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