动态存储空间分配、管理和释放

一、 C程序的存储空间布局

典型的存储空间安排

  • 正文段。这是由 CPU 执行的机器指令部分。通常,这段是可共享的。通常是只读的,防止程序由于意外而修改其指令。
  • 初始化数据段。通常称此段为数据段,包含了程序中需要明确地赋初值的变量。
  • 未初始化数据段。通常称此段为 bss 段,在程序开始执行前,内核将此段中的数据初始化为 0 或 空指针。
  • 栈。自动变量以及每次函数调用时所需保存的信息都放此段中。
  • 堆。通常在堆中进行动态存储分配。(堆应该非常大,未初始化数据和栈之间都是堆)
二、动态存储空间分配
       #include <stdlib.h>
       void *malloc(size_t size);
       void *calloc(size_t nmemb, size_t size);
       void *realloc(void *ptr, size_t size);
       //     若成功,返回非空指针;若失败,返回 NULL
       void free(void *ptr);
  1. malloc 函数
    分配指定字节数的存储区。此存储区的初始值不确定
  2. calloc 函数
    为指定数量指定长度的对象分配存储空间。该空间中的每一位(bit)都初始化为 0
  3. realloc 函数
    增加或减少以前分配区的长度。这里重点说一下 realloc 函数
    (1) 减少存储区的长度,这个简单直接减少就行;
    (2) 增加存储区长度,如果在该存储区后有足够的空间可供扩充,则可在原存储区上向高地址方向扩充,无需移动任何原先的内容;并返回与传给他相同的指针值;
    (3) 如果原存储区后没有足够的空间,则 realloc 分配另一足够大的存储区,再将原来空间的元素搬移过去,然后释放原存储区,返回新分配区的指针。新的区域,初始值不确定。
    注意:realloc 的最后一个参数是存储区的长度,不是新、旧存储区长度之差。
  4. 操作系统如何管理这部分区域?
    其实,这三个函数每次申请指定字节的存储空间,操作系统并不一定是完全按照指定的申请的,操作系统为了效率会多申请一点空间,并且,会记录所申请的空间大小,记录在哪? 记录在返回值所指向地址的前两个字节,为什么要记录呢?不知道你有没有发现,free函数只有一个参数!!!
  5. free 函数如何释放空间?
    free函数只有一个参数,即所要释放的空间的首地址,那我拿到了这个首地址之后,再往前走两个字节,不就知道了我要释放多少空间了么?这就是操作系统如何分配、管理与释放空间的。

这里还有几个需要注意的点:

  • 在动态分配的缓冲区前或后进行写操作,是一件很危险的事,为什么呢?一旦进行写操作,破坏的不仅仅是该区的管理记录信息,在动态分配的缓冲区前后的存储空间很有可能用于其他动态分配的对象,那这就麻烦了。处理起来更加困难。
  • 释放一个已经释放了的块。
  • 调用 free 时所用指针不是 3 个 alloc 函数的返回值。
  • 泄漏(leahage):某进程调用 malloc 函数,但却忘记调用 free 函数,那么该进程占用的存储空间就会连续增加,导致进程地址空间慢慢增加,直至没有空闲空间,性能下降。
  • 每次调用这 3 分配函数中的任意一个或 free 时,他们都进行附加的检错。
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值