存储程序控制(关于C++拷贝控制)

ntechnologytr778 2024-01-15 阅读:9 评论:0
大家好,今天给大家分享存储程序控制,一起来看看吧。void test(){Message m1(&34;), m2(&34;), m3(&34;);Folder f1, f2;m1.save(f1); m1.save(f2);m2.save...

大家好,今天给大家分享存储程序控制,一起来看看吧。

void test(){Message m1(&34;), m2(&34;), m3(&34;);Folder f1, f2;m1.save(f1); m1.save(f2);m2.save(f2);m3.save(f2);m2.remove(f2);}int main(){test();system(&34;);return 0;}

运行结果:

经调试排查原因之后,找到了问题所在:试图对已经被销毁了的对象的指针进行解引用。该bug和“函数返回指向局部变量的指针”所导致的问题类似。我们为Message类定义了析构函数:

Message::~Message(){remove_from_folders();}

这个析构函数的实现与C Primer上的实现完全一致。该析构函数意图在于当一个Message被销毁时,应该清除它的folders中的所有指向它的指针。这看上去合理,可是在这里却导致了内存错误。原因在于,remove_from_folders()操作会访问该Message所在的所有Folder的指针,而若这些Folder的销毁在该Message的销毁之前进行,则操作会试图通过指针解引用,来访问已被销毁的Folder对象。这会导致严重的运行时错误。在本例中,局部变量Folder f1的创建在m1之后,将m1加入f1,test()函数结束时,按照局部变量的销毁顺序,会先销毁后创建的对象f1,于是,m1的析构函数会试图解引用已被销毁对象f1的指针。出现这个问题,是因为在实现的时候没有按照C Primer上的设计正确地实现Folder的析构函数。我们按照如下实现Folder的析构函数:

class Folder{/*其他Folder的声明不变*//*加入Folder的析构函数,以及一个工具函数,对于将要销毁的Folder,这个工具函数负责删除该Folder中所有Message指向它的指针*/private:void remove_from_messages();public:~Folder();};void Folder::remove_from_messages(){for (auto m : messages)m->remFolder(this);}Folder::~Folder(){remove_from_messages();}

此时,Folder的析构函数在Folder被销毁时可以正确地删除所有Message中指向自身的指针,就避免了对已经销毁的对象进行解引用的操作。反过来,若先定义的是f1,后定义的是m1,在m1先销毁时,m1的析构函数也可以正确地删除所有Folder中指向m1的指针。所以,无论Folder先被销毁,还是Message先被销毁,都能够正确地执行析构操作。使用与上面同样的test()函数进行测试,程序可以正常地退出了:

这个例子也给了我们又一次提醒:在C 中,指针与拷贝控制、内存管理一定要万分小心谨慎,一点小的差错也可能导致程序的灾难。

以上就是存储程序控制的内容分享,希望对大家有用。

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权发表,未经许可,不得转载。

«    2024年3月    »
123
45678910
11121314151617
18192021222324
25262728293031
最近发布
热门文章