带有C ++指针的简单代码的行为 [英] Behavior of simple code with pointers in C++

查看:138
本文介绍了带有C ++指针的简单代码的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有以下代码:

sphere * a, * b;
a = new sphere(1.0);
b = a;
b->setRadius(2.0);
delete b;
a->setRadius(4.0);
sphere * c = new sphere(5.0);
b = new sphere(3.0);
cout << a->getRadius() << endl;

结果是什么:

(a) 4.0
(b) 3.0
(c) A segmentation fault.
(d) Compiler error.
(e) The behavior cannot be predicted.



我不认为你需要看到球类,因为它很明显是什么发生了。现在,当我们设置 b = a 时,这意味着 b 指向 code>。然后我们 delete b ,这意味着我们删除 b 指向的那个,这意味着 a 现在不再指向任何东西。所以当我们尝试说 a-> setRadius 时,我们不能。所以我认为这是一个 seg故障

I dont think you'll need to see the sphere class, as its pretty obvious whats going on. Now, when we set b=a, this means bis pointing to a. Then we delete b, which means we delete what b was pointing to, and that means that a is now no longer pointing to anything. So when we try to say a->setRadius, we cant. And so I think thats a seg fault. Am I looking at this the right way?

推荐答案

最多 delete b; 一切都好。下一行( a-> setRadius(4.0); )将触发未定义的行为,因为您正在访问已删除的对象。问题是,90%的时间,它将工作(是的,这是一个问题,因为其他10%的时间,它会崩溃,你会失去了夜晚找到为什么!)

Up to delete b; everything is ok. The next line (a->setRadius(4.0);) will trigger an undefined behaviour, because you are accessing a deleted object. The problem is that 90% of the times it will work (yes, this is a problem, because the other 10% of the times it will crash and you will lose the night finding why!)

为什么这样?这是因为操作符new和delete的许多实现在每次被调用时不会向OS询问存储器。他们问一个大块,然后每次使用它一点。当你删除对象时,内存只被标记为空闲,而不是释放。所以当你访问一个deallocated对象,你正在访问(可能)仍然分配给你的进程,但你不应该使用的内存。在中间有一些你的程序的其他部分可以分配和修改它,或者只是删除操作可以看到有这么多的内存标记为免费,并决定将其返回到操作系统,触发一个SEGFAULT,如果你尝试访问它。一个调试版本的删除可以填充一个模式或零,这样,如果你看它,它是更明显的,它在使用或免费...有很多选项。

Why this? This happens because many implementations of operator new and delete don't "ask" the memory to the OS every time they are called. They ask a big block of it and then use it a little at a time. When you delete your object, the memory is only "marked" as free, and not freed. So when you access a deallocated object, you are accessing memory that (probably) is still allocated to your process, but that you shouldn't use. In the middle some other part of your program could have allocated it and modified it, or simply the delete operator could have seen that there was so much memory "marked as free" and decided to return it to the OS, triggering a SEGFAULT if you try to access it. A "debug" version of the delete could fill it with a pattern or zero it, so that if you watch it it's more evident that it's in use or free... There are many options.

注意:我已经通过new和delete来简化了内存的处理。 正常有一些更多的间接级别。但是它们与讨论无关。

A note: I have simplified the handling of memory by new and delete. "Normally" there are some more levels of indirection. But they are irrelevant to the discussion.

在debug / new / malloc / free的某些实现中,调试会创建内存,而不是被归零, 0xcdcd。这有两个原因。如果我记得正确,一个是0xcc是INT指令的INT 3断点(和0xcdcd是一个多重或类似的东西)。另一个是,如果你在调试器中观察它,模式是很明显看到,而一个所有0x00模式可能更难以区分。

On some implementations of new/delete/malloc/free on debug builds the memory, instead of being zeroed, is filled with 0xcc or 0xcdcd. This is for two reasons. If I remember correctly one is that 0xcc is the Intel instruction for the INT 3 breakpoint (and 0xcdcd is a multiple or something similar). The other is that if you watch it in a debugger, the pattern is quite obvious to see, while an "all 0x00" pattern could be more difficult to distinguish.

这篇关于带有C ++指针的简单代码的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆