在阅读了很多关于此的帖子后,我想澄清下一点:
A* a = new A();
A* b = a;
delete a;
A* c = a; //illegal - I know it (in c++ 11)
A* d = b; //I suppose it's legal, is it true?
Run Code Online (Sandbox Code Playgroud)
所以问题是关于使用已删除指针的副本的值.
我读过,在c ++ 11中读取a导致未定义行为的价值 - 但是读取它的价值b呢?
尝试读取指针的值(注意:这与解除引用它不同)会导致自C++ 14以来的实现定义行为,其中可能包括生成运行时错误.(在C++ 11中它是未定义的行为) 删除后指针本身会发生什么?
假设我们有来自C++ 98的遗留代码:
bool expensiveCheck();
struct Foo;
bool someFunc()
{
Foo *ptr = 0;
if( expensiveCheck() )
ptr = new Foo;
// doing something irrelevant here
...
if( ptr ) {
// using foo
}
delete ptr;
return ptr; // here we have UB(Undefined Behavior) in C++11
}
Run Code Online (Sandbox Code Playgroud)
所以基本上这里的指针用于保持动态分配的数据并同时将其用作标志.对我来说它是可读代码,我相信它是合法的C++ 98代码.现在根据这个问题:
这段代码在C++ 11中有UB.这是真的吗?
如果是,请记住另一个问题,我听说委员会付出了巨大努力,不破坏新标准中的现有代码.如果我在这种情况下没有弄错,这不是真的.是什么原因?这样的代码是否已经被认为是有害的,所以没有人关心它会被打破?他们没有考虑后果?这种优化是如此重要?别的什么?
请看看下面的代码::
#include<iostream>
using namespace std;
int main()
{
int *ptr;
ptr = new int[100000];
cout<<"\n\n address = "<<ptr;
for(long int i=0;i<100000;i++)
*(ptr+i) = i+1;
delete []ptr;
cout<<"\n\n address = "<<ptr;
ptr = new int[5];
cout<<"\n\n address = "<<ptr;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
address = 0xd42490
address = 0xd42490
address = 0xe919d0
Run Code Online (Sandbox Code Playgroud)
为什么,在delete []ptr;它仍然指向它之前的位置之后(见第二个输出)。