With ++ 中有一些与原始指针相关的问题。考虑以下代码
#include <stdio.h>
struct Point {
double x, y;
};
int main(void) {
Point* p = new Point;
delete p;
/*
* Далее выполняется очень большое кол-во разных
* действий связанных с созданием разных объектов,
* включая Point, а также их удалением.
*/
printf("address = %d, x = %f", p, p->x); //строчка X.
return 0;
}
问题:
对于正在创建的下一个对象
Point,只分配了指针指向的内存区域p。这样的巧合可能吗?如果是这样,第 X 行会成功吗?对于下一个创建的NOT TYPE POINT对象,已经分配了一个内存区域,它的开头只是由指针指向的
p。该对象由具有三个字段的结构表示double。可能吗?如果是这样,第 X 行会成功吗?对象释放后为其分配的内存区域
Point被转移到操作系统,然后成为另一个进程的一部分。这种情况可能吗?如果是 - 纯粹从理论上讲,是否可以通过 p 指针引用另一个进程的数据?
让我们从这不是 C 而是 C++ 的事实开始。
1.2. 在
delete p;, 所指向的内存p是空闲的之后,所以它可以被分配给任何东西(如果相应的连续空闲内存的大小允许的话)。所以你描述的很有可能。请参阅下面的行x。该行
x是半正确的:) - 您可以在任何情况下显示地址 -就像变量的内容一样p,这并不意味着它是正确的,它可以被访问。仅当p->x您访问正确分配且未释放的内存(或变量的地址 - 例如)。之后
delete p;它就变成了 UB(很明显,在那之后p = &pp;发布本身delete p;就是 UB)。如果在删除和输出之间您再次分配
p了一个指向已分配内存或对象地址的指针Point,则该行是x正确的。简而言之。你可以说得更详细一点,但是...
第 X 行会被执行,但执行的结果是不可预测的,并且可能总是或有时是错误的。甚至结果也总是不完全正确,而是编写此错误代码的人所期望的。
问题中给出的代码是错误的代码。它将编译,但运行时会出现错误(如果适当的编译器以良好的方式布置数据结构,则有时可能会发生错误,并且可能永远不会发生错误)。在 C++ 语言的语言级别没有针对此类错误的保护措施。为此(由于缺乏针对此类错误的保护),C ++ 语言受到许多人的批评。但是,如果程序员自己控制这些潜在的错误时刻,C++ 语言允许您编写更高效的程序。