内存跟踪___堆

     前面已经探讨了栈结构 这里对堆也跟踪一下:

     堆的分配规则和栈不一样  堆的地址是从小到大分配的 并且连续分配的两个内存块的起始地址是肯定不同的。
     
     写在前面: 关于内存所谓的空闲区值:
                    经常写代码忘了初始化的人可能会注意到,每次定义一个整形变量没有初始化直接使用  往往每次都得到一个很大的负数  不是说没有分配的内存都是随机的么?看这个示例:
    int main()
     {
          int a;
          int* pb = new int;

          cout<<"a is from stack, b is from heap"<<endl;
          cout<<"(int)a= "<<a<<endl;
          cout<<"(int)b= "<<*pb<<endl;
    
          cout<<"(hex)a= "<<hex<<a<<endl;
          cout<<"(hex)b= "<<hex<<*pb<<endl;
          char* pa = (char*)&a;
          cout<<"(char)a= "<<pa<<endl;
          cout<<"(char)b= "<<(char*)pb<<endl;
    
          delete pb;
          return 0;
     }
     vc++6.0输出结果:
     
     我相信这里面出现的这两个字大家都很熟悉了,就连上面的两个负整数应该都是异常眼熟吧  接下来  揭开谜底:
     对于栈和堆的空闲区(未被覆盖前) 是会被默认初始化的, 栈内存初始化为CC 堆初始化为CD的  初看起来了解这个意义不大  但这是下面所说的一些东西的基础。
     示例2:
     int main()
     {
          int*a = new int;
          int*b = new int;
          int*c = new int;

          delete a;
          delete b;
          delete c;
     
          return 0;
     }
     调试 得到
     a = 00382a48
     b = 00382a90
     c = 00382ad8
     内存跟踪:
     
     这里面包含了很多信息
     1.b指针指向的地址处(00382a90) 被默认初始化为CD
     2.空闲区两头是有四个字节的界定符的 这里是FD FD FD FD
     3.继续往上看  00382a70处  有一个地址00382a28
     4.下一个地址 00382a74处 有一个地址00383ab8
     在这里我们不妨假设这两个地址就是已经被分配的内存的下一块和上一块
     接下来  我们对00382a28进行跟踪:
     
     在该地址下面不远处 我们找到了00382a48 也就是指针a指向的地址  那么到了这里我们可以看出:
     堆中每一个内存块是被连接到一个链表上的  并且每一个空闲区都被封在一个结构体中
      这个结构体至少应该包含
      该数据块的前驱和后继
      该数据块大小
      数据块的界定符
      数据块本身

     在这里我们可以看出 放在数据块前面的数据区大小=00382a48-00382a28=32个字节
      同时对其中另一部分数据进行分析 初步可以猜测:
     00382a38  分配的元素类型所占字节数 这里是sizeof(int)
     00382a3c 分配该类型元素的个数

     到这里也可以明白为什么动态分配一个数组int* p=new int[5] 只需要delete []p 就可以了 因为结构体保存了元素个数

     随便再说一下  对于CD CC只针对于还未使用过的内存  比如像栈这种动态收缩的结构  同一个内存不同时刻会存放不同的变量  在使用后回收时 只改变栈顶指针  数据是还在的  所以不是CC
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值