C++ 删除C++;指向对象的指针

C++ 删除C++;指向对象的指针,c++,memory,pointers,memory-management,C++,Memory,Pointers,Memory Management,我认为delete命令会释放我分配的内存。有人能解释一下为什么删除后我的内存仍在使用中吗 class Test { public: int time; }; int main() { Test *e; e = new Test; e->time = 1; cout << e->time << endl; delete e; e->time = 2; cout << e-

我认为delete命令会释放我分配的内存。有人能解释一下为什么删除后我的内存仍在使用中吗

class Test
{
public:
    int time;
};

int main()
{
    Test *e;

    e = new Test;

    e->time = 1;
    cout << e->time << endl;

    delete e;

    e->time = 2;
    cout << e->time << endl;

    return(0);
}
类测试
{
公众:
整数时间;
};
int main()
{
测试*e;
e=新试验;
e->time=1;
cout-time=2;
cout-time=2


谢谢!

访问被删除的对象是一种未定义的行为。任何事情都可能发生。

访问被删除的对象是一种未定义的行为。任何事情都可能发生。

未定义的行为就是这样,未定义。如果愿意,它甚至可以工作。

未定义的行为就是这样,未定义。如果愿意,它甚至可以工作。

删除指向已删除对象的指针是未定义的。该对象的内存可能尚未被覆盖,因此您的对象仍在那里(如果它工作正常的话).

取消对已删除对象的指针的引用是未定义的。该对象的内存可能尚未被覆盖,因此您的对象仍然存在(如果它可以正常工作的话)

我预计在e->time=2之后会出现seg故障

您不应该“期望”任何事情发生;您正在调用未定义的行为,根据定义,该行为是未定义的。这意味着您不能再对程序的状态做出任何合理的期望

我预计在e->time=2之后会出现seg故障

您不应该“期望”任何事情发生;您正在调用未定义的行为,根据定义,该行为是未定义的。这意味着您不能再对程序的状态做出任何合理的期望。

当您“删除”时内存,您基本上是将分配的内存返回堆。这只是意味着用于组织堆内存的数据结构被更新,以指示内存现在可以使用。它不会被清除或诸如此类的内容。您正在访问仍然存在的内存,但此时属于操作系统。这是未定义的行为

编辑:

顺便说一下,当您尝试从没有读取权限的段读取内存时,会发生seg错误。在平面内存模型中,这可能意味着您尝试在内核空间中读取内存;可能是因为您取消了对错误指针的引用。

当您“删除”时内存,您基本上是将分配的内存返回堆。这只是意味着用于组织堆内存的数据结构被更新,以指示内存现在可以使用。它不会被清除或诸如此类的内容。您正在访问仍然存在的内存,但此时属于操作系统。这是未定义的行为

编辑:


顺便说一下,当您尝试从没有读取权限的段读取内存时,会发生seg错误。在平面内存模型中,这可能意味着您尝试在内核空间中读取内存;可能是因为您取消了对错误指针的引用。

指针是内存中地址的容器。您可以始终使用 声明的指针,但除非它初始化为您拥有的内存,否则可能会出现混乱和更糟的情况

Test *e;
e->time = 2;
也会编译但不会工作。请尽量减少此类混淆,以便:

{
  boost::scoped_ptr<Test> e(new Test);

  e->time = 1;
  cout << e->time << endl;

  e->time = 2;
  cout << e->time << endl;
}
{
boost::范围内的测试(新测试);
e->time=1;
cout-time=2;

cout time指针是内存中地址的容器。您始终可以使用声明的指针,但除非它初始化为您拥有的内存,否则可能会出现混乱和更糟的情况

Test *e;
e->time = 2;
也会编译但不会工作。请尽量减少此类混淆,以便:

{
  boost::scoped_ptr<Test> e(new Test);

  e->time = 1;
  cout << e->time << endl;

  e->time = 2;
  cout << e->time << endl;
}
{
boost::范围内的测试(新测试);
e->time=1;
cout-time=2;

时间会告诉你,你做了一件坏事。时间会告诉你,你做了一件坏事。时间会告诉你,你做了一件坏事。正如其他人所说,你所做的是错误的,但你不能期待任何特殊的行为

在大多数现代系统上可能发生的情况是,
e
所分配和占用的内存位于映射为对您的程序有效的内存页上,并且您已经删除了
d
e
,这一事实并不会撤消该映射


因此,您仍然在访问应用程序从操作系统获得使用权限的内存。因此,没有分段错误。但是,如果在
delete e
和访问该内存之间发生足够多的事情,页面可能会被重新映射。然后您会遇到seg错误。

正如其他人所说,您所做的是错误的,但是不能期望有任何特殊的行为

在大多数现代系统上可能发生的情况是,
e
所分配和占用的内存位于映射为对您的程序有效的内存页上,并且您已经删除了
d
e
,这一事实并不会撤消该映射


因此,您仍在访问应用程序有权从操作系统使用的内存。因此,没有分段错误。但是,如果在
delete e
和访问该内存之间发生足够多的事情,则页面将被重新映射。然后,您会遇到seg错误。

测试中没有中断的原因是一个组合幸运的是,你有一个非常简单、非常短的例程。你正在处理进程空间中的内存,而你的指令太少,例程可能一次就运行

delete
关键字在进程的内存管理器中取消分配内存,但它不会清除内存或(通常)接触内存太多。如果以后使用内存,则值会更改,但在此之前,无论您上次将其设置为什么,都将保留(或多或少,这毕竟是未定义的)

考虑到您的例程只有几个指令,处理器很有可能按顺序执行这些指令,而不在其间切换到另一个进程。这会产生副作用,即其他任何指令都不可能过度执行