C 堆内存管理

在Win32 程序中每个进程都占有4GB的虚拟地址空间,这4G的地址空间内部又被分为代码段,全局变量段堆段和栈段,栈内存由函数使用,用来存储函数内部的局部变量,而堆是由程序员自己申请与释放的,系统在管理堆内存的时候采用的双向链表的方式,接下来将通过调试代码来分析堆内存的管理。

堆内存的双向链表管理

下面是一段测试代码

#include <iostream>
using namespace std;

int main()
{
    int *p = NULL;
    __int64 *q = NULL;
    int *m = NULL;

    p = new int;
    if (NULL == p)
    {
        return -1;
    }
    *p = 0x11223344;

    q = new __int64;
    if (NULL == q)
    {
        return -1;
    }
    *q = 0x1122334455667788;

    m = new int;
    if (NULL == m)
    {
        return -1;
    }
    *m = 0x11223344;

    delete p;
    delete q;
    delete m;
    return 0;
}

我们对这段代码进行调试,当代码执行到delete p;位置的时候(此时还没有执行delete语句)查看变量的值如下:

p q m变量的地址比较接近,这三个指针变量本身保存在函数的栈中。从图中看存储这三个变量内存的地址好像不像栈结构,这是由于在高版本的VS中默认开启了地址随机化,所以这里看不出来这些地址的关系,但是如果在VC6里面可以很明显的看到它们在一个栈结构中。

我们将p, q, m这三者所指向的内存都减去 0x20 得到

p - 0x20 = 0x00035cc8 - 0x20 = 0x00035ca8
q - 0x20 = 0x00035d08 - 0x20 = 0x00035ce8
m - 0x20 = 0x00035d50 - 0x20 = 0x00035d30

在内存窗口中分别查看p - 0x20, q- 0x20, m- 0x20 位置的内存如下

通过观察发现p - 0x20处前8个字节存储了两个地址分别是 0x00035c38、0x00035ce8。是不是对0x00035ce8 这个地址感到很熟悉呢,它就是q - 0x20 处的地址,按照这个思路我们观察这些内存发现

内存地址

前四个字节

后四个字节

0x00035ca8

0x00035c38

0x00035ce8

0x00035ce8

0x00035ca8

0x00035d30

0x00035d30

0x00035ce8

0x00000000

看到这些地址有没有发现什么呢?没错,这个结构有两个指针域,第一个指针域指向前一个节点,后一个指针域指向后一个节点,这是一个典型的双向链表结构,你没有发现?没关系,我们将这个地址整理一下得到下面这个图表

既然知道了它的管理方式,那么接着往后执行delete语句,这个时候再看这些地址对应的内存中保存的值

内存地址

前四个字节

后四个字节

0x00035CA8

0x00035d70

0x000300c4

0x00035ce8

0x00035c38

0x00035d30

0x00035d30

0x00035ce8

0x00000000

系统已经改变了后面两个节点中next和pre指针域的内容,将p节点从双向链表中除去了。而这个时候仔细观察p节点中存储内容发现里面得值已经变为 0xfeee 了。

我们在delete的时候并没有传入对应的参数告知系统该回收多大的内存,那么它是怎么知道该如何回收内存的呢。我们回到之前的那个p - 0x20 内存的图上看,是不是在里面发现了一个0x00000004的值,其实这个值就是当前节点占了多少个字节,如果不相信,可以看看q- 0x20 和m - 0x20 内存处保存的值看看,在对应的偏移处是不是有 8和4。系统根据这个值来回收对应的内存。


本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏孟永辉

任性的苹果,任性的库克

或许在人类历史上还没有哪一个科技公司会像苹果般任性,任性到可以不顾及用户的感受。随着苹果发布会的新鲜“上线”,我们再次见识到了苹果的任性。价格再度刷新史上最高、...

11010
来自专栏孟永辉

锤子手机推“无限屏”新机:让我们为老罗的创新点赞

人们对于锤子手机的发布会的期待其实更多的是在看罗永浩的“单口相声”。无论锤子手机如何,观众依然能够在锤子手机发布会上过一回嘴瘾。罗永浩对于自己,对于友商,对于行...

13050
来自专栏孟永辉

饿了么并入口碑,一场“非典型”新零售大战的开始

如果你了解互联网巨头的套路,你就会发现他们会不断用资本的力量去拓展自己的势力范围,并且建构一个能够将人们所有的生活场景全部都囊括其中的生态体系。饿了么并入口碑仅...

8310
来自专栏孟永辉

拼多多、趣头条上市,反驳消费升级的无效样本

最近,有关消费升级与消费降级的讨论一直都没有停止过。作为一个新的风口和方向,人们对于消费升级和消费降级的谈论无可厚非,因为只有深入讨论才能找到合适的发展方向。但...

7310
来自专栏孟永辉

共享单车落幕:上海凤凰诉ofo或在情理之中

共享单车浩浩荡荡的发展历程伴随着资本的退却而最终落幕。尽管共享单车市场上摩拜投身美团总算是有了一个好归宿,哈罗单车对于三四线的深度布局实现了逆袭,ofo依然在仗...

8810
来自专栏孟永辉

恒大入主法拉第,FF91真的要来了吗?

自恒大入主法拉第之后,FF91落地的步伐似乎开始逐步加快。在许家印到法拉第公司考察之后,FF91在落地到中国的步伐更加快速。就在上周,恒大法拉第未来智能汽车集团...

7920
来自专栏孟永辉

或许,9月12日的苹果新品发布会依然会让人失望!

正如每一次的苹果邀请函都带给我们不一样的感受一样,今年9月12日的苹果发布会的邀请函依然让我们浮想联翩。这或许是苹果以往营销套路的延续——通过给人一个极具想象力...

10720
来自专栏孟永辉

BAT、TMD加持新技术背景下,互联网家装如何蝶变新生?

几乎所有的“互联网+”模式都存在同样的问题,那就是对于行业内在运行逻辑改造的无力与浅层。互联网家装同样如此。我们看到,尽管互联网家装改变了人们获取用户的方式和手...

8210
来自专栏happyJared

1万步21天钉钉运动大神赛

  目前所在的企业,从入职开始到现在,内部沟通协作的主要软件也就是钉钉。三月初的时候,偶然在钉钉运动一栏中发现了这个活动,当时也没怎么犹豫,果断支付了2元契约金...

26110
来自专栏孟永辉

马云退休,一个全新的互联网时代或将开始

今天,马云退休的消息无疑是一个焦点。对于马云退休的原因,外界依然有很多的猜测。几乎可以确定的是,未来马云将会从事自己心仪的教育事业,并将会持续发挥自己在教育事业...

14520

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励