0

我想知道删除是如何工作的?在主要功能中,我删除了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;
}
4

5 回答 5

6

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

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

现在有效的事实并不意味着它将永远有效。例如,如果您将代码移动到另一台机器或重新启动计算机,代码可能会出现段错误。

将指针设置为NULLafter始终是一个好习惯delete。甚至更好用smart pointers

于 2013-04-29T12:37:48.677 回答
2

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

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

在我的测试用例中,它回来0delete

于 2013-04-29T12:38:03.100 回答
1

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

于 2013-04-29T12:39:06.680 回答
1

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

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

于 2013-04-29T12:39:30.830 回答
1

抱歉,我无法发表评论...我编译了您的代码,您可以观察到 c2fact 替换了您刚刚销毁的 cfact (输出为

c2_fact 类:公共工厂

c2_fact 类:公共工厂)

顺便说一句,如果你把“cfact->Hello();” 在您创建 c2fact 之前,程序可能会崩溃(这似乎是您所希望的),因为 mem 块不受任何对象的影响。请注意,此行为可能会根据内存监视和其他正在运行的进程而改变。

于 2013-04-29T14:45:54.893 回答