系统是如何区分已分配内存,和未分配内存的?

时间:2022-09-02 00:29:32
系统是如何区分已分配内存,和未分配内存的?
比如用new分配出内存,用指针 p 指向它,然后再次delete这块内存,
我发现,

*p取值的话,前后的值是不同的。
我不理解,因为delete是释放那块内存,但是并没有改写这块内存呀,为何取值会不同呢?

当然,你会说,释放的空间是不能用的,这个我也知道,我就是想明白一下,释放了的空间,在内存块不被改写的情况下,为何用同一个物理指针取它的值的话,值却真的变了,这是为什么呢?


#include <iostream>
using namespace std;

int main()
{
    int *a=new int;
    *a=90;
    cout << "值为:" << *a << endl;
    cout << "地址为:" << a << endl;
    delete a;
    cout << "值为:" << (int)*a << endl;  //此时值已经变了(release版本照样变)
    cout << "地址为:"  << a << endl;
    
cin.get();
return 0;
}

12 个解决方案

#1


那说明系统回收这块堆的时候,还额外作了一些初始化的处理,对你使用没有关系吧,你delete再使用,本身就是越界。

#2


这要看编译器是如何实现delete的了

http://student.csdn.net/space.php?uid=43658&do=blog&id=10880

这篇文章作者做了自己的分析,我这也没这么多编译器,就不一一测试了

简单的说,不同编译器对delete的实现可能不一样,有可能的实现就是在声明该内存不属于本程序外,可能赋值成了一个随机值,也可能是别的操作

#3


野指针问题,一般用delete释放一个new分配的内存时要将这个指针赋值为NULL,否则内存是释放了,但是指向的地址还是存在的,但是地址里面存放的内容就不一定是以前的内容了,系统会对释放的内存重新处理的

#4


delete了之后,原来的那个地址不再存放90了
指针指向一个随机值,所以不会是原来那个值了
而原来那个地址不知道存放了什么内容
地址还是原来那个地址
应该是这样理解的

#5


引用 4 楼 lixiufengqqqq 的回复:
delete了之后,原来的那个地址不再存放90了
指针指向一个随机值,所以不会是原来那个值了
而原来那个地址不知道存放了什么内容
地址还是原来那个地址
应该是这样理解的

空间释放,这个随机值是谁写进去的呢?

#6



   学习了很多。

#7


你释放的空间;只是表示你的代码没有去修改;不代表OS没有分配给其他进程;也不代表其他进程不去修改;可能OS自己用了;自己修改了;

#8


    内存管理是操作系统底层的职责,你在程序中delete了这块内存,其实就是在向操作系统底层说明我的程序已经不需要用到这一块内存了,操作系统就会把这块内存标记为空闲(free)的状态,这就意味着操作系统底层可能会把这块内存分配给别的线程、进程使用了,因为操作系统是多进程、多线程的,可能在你的线程进行下一步操作之前,操作系统底层就已经把这一块内存分配出去了,因为导致你看到的内容是完全不同的;
总之,一旦你delete了某块内存,就意味着这块内存中的容易是无法确定的了

#9


[Quote=引用 5 楼 jxshn 的回复:]
引用 4 楼 lixiufengqqqq 的回复:
delete了之后,原来的那个地址不再存放90了
指针指向一个随机值,所以不会是原来那个值了
而原来那个地址不知道存放了什么内容
地址还是原来那个地址
应该是这样理解的

空间释放,这个随机值是谁写进去的呢?

有可能是你原来申请过内存,然后释放掉之后,原来内存中的内容

#10


楼住如果不是必需,就不要研究这个问题了,很难讲清楚的。

如果一定要研究,首先要清楚操作系统的内存管理细节,还要清楚你的编译器对delete的处理细节,貌似很有难度啊。

#11


再顶下,确实可以不研究,但是想通过这个了解一个机理。

#12


经典问题 学习了!

#1


那说明系统回收这块堆的时候,还额外作了一些初始化的处理,对你使用没有关系吧,你delete再使用,本身就是越界。

#2


这要看编译器是如何实现delete的了

http://student.csdn.net/space.php?uid=43658&do=blog&id=10880

这篇文章作者做了自己的分析,我这也没这么多编译器,就不一一测试了

简单的说,不同编译器对delete的实现可能不一样,有可能的实现就是在声明该内存不属于本程序外,可能赋值成了一个随机值,也可能是别的操作

#3


野指针问题,一般用delete释放一个new分配的内存时要将这个指针赋值为NULL,否则内存是释放了,但是指向的地址还是存在的,但是地址里面存放的内容就不一定是以前的内容了,系统会对释放的内存重新处理的

#4


delete了之后,原来的那个地址不再存放90了
指针指向一个随机值,所以不会是原来那个值了
而原来那个地址不知道存放了什么内容
地址还是原来那个地址
应该是这样理解的

#5


引用 4 楼 lixiufengqqqq 的回复:
delete了之后,原来的那个地址不再存放90了
指针指向一个随机值,所以不会是原来那个值了
而原来那个地址不知道存放了什么内容
地址还是原来那个地址
应该是这样理解的

空间释放,这个随机值是谁写进去的呢?

#6



   学习了很多。

#7


你释放的空间;只是表示你的代码没有去修改;不代表OS没有分配给其他进程;也不代表其他进程不去修改;可能OS自己用了;自己修改了;

#8


    内存管理是操作系统底层的职责,你在程序中delete了这块内存,其实就是在向操作系统底层说明我的程序已经不需要用到这一块内存了,操作系统就会把这块内存标记为空闲(free)的状态,这就意味着操作系统底层可能会把这块内存分配给别的线程、进程使用了,因为操作系统是多进程、多线程的,可能在你的线程进行下一步操作之前,操作系统底层就已经把这一块内存分配出去了,因为导致你看到的内容是完全不同的;
总之,一旦你delete了某块内存,就意味着这块内存中的容易是无法确定的了

#9


[Quote=引用 5 楼 jxshn 的回复:]
引用 4 楼 lixiufengqqqq 的回复:
delete了之后,原来的那个地址不再存放90了
指针指向一个随机值,所以不会是原来那个值了
而原来那个地址不知道存放了什么内容
地址还是原来那个地址
应该是这样理解的

空间释放,这个随机值是谁写进去的呢?

有可能是你原来申请过内存,然后释放掉之后,原来内存中的内容

#10


楼住如果不是必需,就不要研究这个问题了,很难讲清楚的。

如果一定要研究,首先要清楚操作系统的内存管理细节,还要清楚你的编译器对delete的处理细节,貌似很有难度啊。

#11


再顶下,确实可以不研究,但是想通过这个了解一个机理。

#12


经典问题 学习了!