在这些 C++ 代码行中:
int * p = new int(33);
delete(p);
*p = 13;
cout << *p << endl;
输出为 13;
P最初指向堆上的一个地址,然后我使用delete关键字释放p分配的内存地址,但仍然可以为内存地址分配23的值;这是 p 在“int * p = new int(33)”之后指向的堆上的相同地址,还是 p 在使用 delete(p) 之后指向堆栈上的地址?
在这些 C++ 代码行中:
int * p = new int(33);
delete(p);
*p = 13;
cout << *p << endl;
输出为 13;
P最初指向堆上的一个地址,然后我使用delete关键字释放p分配的内存地址,但仍然可以为内存地址分配23的值;这是 p 在“int * p = new int(33)”之后指向的堆上的相同地址,还是 p 在使用 delete(p) 之后指向堆栈上的地址?
它仍然指向相同的地址(您可以通过打印地址来判断)。您有时会看到人们在释放内存后分配NULL
或nullptr
或0
指针,以确保他们不会尝试取消引用已释放的内存,因为它没有为他们分配 null。这允许他们拥有如下代码:
if (p != nullptr)
//do something with p, it hasn't been freed and set to nullptr
如果它在被释放时没有设置为 null,这很难做到,但请注意,智能指针提供了一种更安全、更一致的替代方案。
您获得正确输出的原因是undefined behavior。它可能会崩溃,它可能会爆炸,或者它可以工作。我猜它选择了工作。
删除p
向管理内存(操作系统)的人发出信号,表明底层空间现在可以自由地由其他人重新分配以供自己使用。p
但是,仍然指向相同的内存位置,并且可以取消引用以获得该内存中内容的值——请注意,由于该内存现在可能被其他人使用,因此底层位可能与以前不同。
是的,它仍然指向堆,但是那个内存位置并不稳定。操作系统可以随时回收它,因此不能保证该内存位置的值就是您设置的值。
此外,据我所知,所有动态内存分配都发生在堆上,而不是堆栈上。堆栈是为参数和局部变量保留的。