zoukankan      html  css  js  c++  java
  • 进程环境之存储器分配

    ISO C说明了三个用于存储器空间动态分配的函数:

    (1)malloc。分配指定字节数的存储区。此存储区中的初始值不确定。

    (2)calloc。为指定数量具有指定长度的对象分配存储空间。该空间中的每一位都初始化为0。

    (3)realloc。更改以前分配区的长度(增加或减少)。当增加长度时,可能需要将以前分配区的内容移到另一个足够大的区域,以便在尾端提供增加的存储区(此时,返回新分配区的指针,否则返回原来的指针值),而新增区域内的初始值则不确定。

    #include <stdlib.h>
    
    void *malloc( size_t size );
    void *calloc( size_t nobj, size_t size );
    void *realloc( void *ptr, size_t newsize );
    三个函数返回值:若成功则返回非空指针,若出错则返回NULL
    
    void free( void *ptr );

    这三个分配函数所返回的指针一定是适当对齐的,使其可用于任何数据对象。

    因为这三个alloc函数都返回通用指针void *,所以如果在程序中包括了#include <stdlib.h>(以获得函数原型),那么当我们将这些函数返回的指针赋予一个不同类型的指针时,就不需要显式地执行类型强制转换。

    函数free释放ptr指向的存储空间。被释放的空间通常被送入可用存储区池,以后,可在调用上述三个分配函数时再分配。

    realloc函数使我们可以增、减以前分配区的长度(最常见的用法是增加该区)。增加该区时,如果在该存储区后有足够的空间可供扩充,则可在原存储区位置上向高地址方向扩充,无需移动任何原先的内容,并返回传送给它的同样的指针值。如果在原存储区后没有足够的空间,则realloc分配另一个足够大的存储区,将原存储区中的内容复制到新分配的存储区。然后,释放原存储区,返回新分配区的指针。因为这种存储区可能会移动位置,所以不应当使任何指针指到该区中。

    注意,realloc的最后一个参数是存储区的newsize(新长度),它不是新、旧存储区长度之差。作为一个特例,若ptr是一个空指针,则realloc的功能与malloc相同,用于分配一个指定长度为newsize的存储区。

    这些分配例程通常用sbrk(2)系统调用实现。该系统调用扩充(或缩小)进程的堆。

    虽然sbrk可以扩充或缩小进程的存储空间,但是大多数malloc和free的实现都不减少进程的存储空间。释放的空间可供以后再分配,但通常将它们保持在malloc池中而不返回给内核。

    应当注意的是,大多数实现所分配的存储空间比所要求的要稍大一些,额外的空间用来记录管理信息——分配块的长度、指向下一个分配块的指针等等。这就意味着如果超过一个已分配区的尾端进行写操作,则会重写后一个块的管理记录。这种类型的错误时灾难性的,但是因为这种错误不会很快暴露出来,所以也就很难发现。同样,在已分配区起始位置之前进行写操作会重写本块的管理记录。

    在动态分配的缓冲区前或后进行写操作,破坏的可能不仅仅是该区的管理记录信息。在动态分配的缓冲区前后的存储区很可能用于其他动态分配的对象。这些对象与破坏它们的代码可能无关,这造成寻求信息破坏的源头更加困难。

    其他可能产生的致命性错误是:释放一个已经释放了的块;调用free时所用的指针不是三个alloc函数的返回值等。如若一个进程调用malloc函数,但却忘记调用free函数,那么该进程占用的存储器就会连续增加,这被称为泄漏(leakage)。不调用free函数以释放不再使用的空间,那么进程地址空间长度就会慢慢增加,直至不再有空闲空间。此时,由于过度的分页开销,因而使性能下降。

    因为存储器分配出错很难跟踪,所以某些系统提供了这些函数的另一种实现版本。每次调用这三个分配函数中的任意一个或free时,它们都进行附加的检错。在调用连接编辑器时指定一个专用库,则在程序中就可使用这种版本的函数。此外还有公共可用的资源,在对其进行编译时使用一个特殊标志就会使附加的运行时检查生效。

    本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/

  • 相关阅读:
    P1197 [JSOI2008]星球大战[并查集+图论]
    P1955 [NOI2015]程序自动分析[离散化+并查集]
    取模运算律[简单数学]
    P1462 通往奥格瑞玛的道路[最短路+二分+堆优化]
    P1330 封锁阳光大学[搜索+染色]
    P1168 中位数[堆 优先队列]
    P2661 信息传递[最小环+边带权并查集]
    P1080 【NOIP 2012】 国王游戏[贪心+高精度]
    P2085 最小函数值[优先队列]
    【转】priority_queue的用法
  • 原文地址:https://www.cnblogs.com/nufangrensheng/p/3508273.html
Copyright © 2011-2022 走看看