C++ 内存访问:为什么不会崩溃以及如何强制执行?

C++ 内存访问:为什么不会崩溃以及如何强制执行?,c++,C++,我希望下面的代码会生成某些内存访问错误,但它不会。有没有办法在编译期间强制执行它 #include <iostream> class B {}; class D : public B { public: int d; }; using namespace std; main() { B *pB = new B; ((D*)pB)->d = 2; cout << ((D*)pB)->d << endl; } 据我所知,将

我希望下面的代码会生成某些内存访问错误,但它不会。有没有办法在编译期间强制执行它

#include <iostream>
class B {};
class D : public B
{ public: int d; };

using namespace std;

main()
{
    B *pB = new B;
    ((D*)pB)->d = 2;
    cout << ((D*)pB)->d << endl;
}
据我所知,将指针投射到D不会改变内存分配,因此访问D应该是非法的,对吗?

是的,访问D是非法的,并且您的代码具有未定义的行为


< C++中没有崩溃的概念,所以请求一种可移植的方法来创建崩溃是没有意义的。如果程序的行为未定义,则它是不可移植的,并且语言规则不会告诉您程序在做什么。

这是非法的,但是你正在进行强制转换,它告诉编译器你知道你在做什么,在不知道结果的情况下不要这样做,它会将你的指针从B*转换为a D*,同时在指向的位置仍然是B obhect。因此,这里的结果是未定义的,因为您正在访问越界


<> P>也可以选择C++样式转换,而C样式的转换则使用C样式的转换,因为它们一般都比较安全。

因为通常在后台处理内存分配的方式,通常不会造成崩溃。


还有第三方产品可以检查这种类型的错误,在这种情况下是缓冲区溢出。只需搜索内存调试器C++。Windows的大多数工具都是商业化的,但可能有免费的。

这不是格式良好的C++。@ KeRek SB——更不用说它是恐怖的C++了。使用名称空间…,原始指针而非智能指针,C样式转换,不正确的主声明,次优格式设置有争议,当然,在需要的地方使用endl\n。。。哦,是的,然后是破坏一切的UB。它实际上有点令人印象深刻,这么多的失败可以塞进这么少的行。抱歉,这正是我问题的第二部分:如何执行检查。@user180574:在你的问题中,你没有这样问过。就像title@user180574当前位置你能不能a让你的问题独立起来?题目不是问题的一部分,b具体说明你到底想要什么?但要注意,我们通常只能为具有定义行为的C++程序提供指导。很难保证当任何事情发生时,任何一件特定的事情都会发生。@user180574引用标准的未定义行为:本国际标准不要求的行为。。因此,既然一旦调用UB,编译器就可以对整个程序执行任何操作,那么答案就是你不能。解决方案是永远不要通过知道规则和你在做什么来调用UB。不只是访问的结果是未定义的。整个程序的行为未定义。是的,整个程序将未定义,但原因是来自强制转换,试图访问可能存在或可能不存在的内容。强制转换不会将B对象转换为D对象。如果是的话,那可能就好了。它所做的是将B*转换成D*,它仍然指向原始的B对象,这是自找麻烦。好的,我不是很清楚,尽管这是我的意思,我已经更新了答案。请澄清。只为类B的实例分配了空间。如果类D大于B,则访问未分配的内存。没有关于如何分配程序内存的信息。如果操作系统只在必要时进行分配,那么问题就存在了。