在C ++中与delete关键字运算符混淆

时间:2013-04-29 12:35:53

标签: c++ new-operator factory-pattern virtual-functions delete-operator

我想知道删除是如何工作的? 在主要功能中,我删除了cfact object。但仍然cfact->Hello()工作而不是抛出错误。 在我发现删除时发现的调试时,cfact释放了内存。只要factory* c2fact = newfun.Newfun("c2_fact");行执行cfact获取一些内存位置。

如何?请帮助我理解这个概念..

class factory{

public:
    virtual void Hello() = 0;
};
class c_fact: public factory
{
public:
    void Hello(){
    cout << "class c_fact: public factory"<<endl;
    }
};
class c2_fact: public factory
{
public:
    void Hello(){
    cout << "class c2_fact: public factory"<<endl;
    }
};

class callFun{
public:
    virtual factory* Newfun(string data)
    {
        if(data == "c_fact")
            {return new c_fact;}
        else
            {return new c2_fact;}
    }
};
class newFun:public callFun{
public:
    factory* Newfun(string data)
    {
        if(data == "c_fact")
            {return new c_fact;}
        else if (data == "c2_fact")
            {return new c2_fact;}
    }
};
int main()
{
    newFun newfun;
    factory* cfact = newfun.Newfun("c_fact");
    delete cfact;                              //Deleted the instance
    factory* c2fact = newfun.Newfun("c2_fact");
    cfact->Hello();//Still it prints the output
    c2fact->Hello();
    system("pause");
    return 0;
}

5 个答案:

答案 0 :(得分:5)

delete实际上并未使其指向的内容无效。它只是告诉操作系统内存可以用于其他东西并且程序不再需要它了。

如果没有被其他数据覆盖,您的数据仍然会在内存中,并且仍然可以访问。这是许多错误的原因,这些错误在开发阶段未被发现并且稍后出现。

现在正在运作的事实并不意味着它将始终有效。例如,如果将代码移动到另一台计算机,或者重新启动计算机,则代码可能会出现段错误。

NULL之后设置指向delete的指针始终是一个好习惯。或者甚至更好地使用smart pointers

答案 1 :(得分:2)

这是未定义的行为,很可能这是有效的,因为方法Hello没有使用任何类变量,因此没有使用this指针。尝试在this中输出Hello,您应该在调用delete后看到无效指针:

std::cout << std::hex << this << << std::endl ;

在我的测试用例中,它在0

之后返回delete

答案 2 :(得分:1)

取消引用已删除的指针是未定义的行为。这意味着任何事情都可能发生,包括看似“工作”的程序。你不能依赖任何这样的行为。

答案 3 :(得分:1)

当您删除内存时,它会被释放。但是,内容通常不会改变,所以写入该内存的任何内容在删除后仍然存在,但是您不知道它将保留多长时间,因为其他函数可以抓取它并用自己的数据覆盖它。

在某些编译器上,在调试模式下编译时,会标记内存,以便您可以通过重用已删除的指针来检测此类错误。但是,这不一定是默认值。因此,您永远不应该重用已删除的指针。

答案 4 :(得分:1)

对不起我无法发表评论...... 我编译了你的代码,你可以观察到c2fact替换了你刚刚销毁的cfact(输出是

  

class c2_fact:public factory

     

class c2_fact:公共工厂   )

BTW如果你把“cfact-&gt; Hello();”在创建c2fact之前,程序可能会崩溃(这是您希望的),因为mem块不会受到任何对象的影响。请注意,此行为可能会更改,具体取决于内存监视和其他正在运行的进程...

希望其他答案(特别是名字的答案)为您提供所寻求的信息。