繁体   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