zoukankan      html  css  js  c++  java
  • 详解C语言中内存分配函数

    6217760-b69377db74a51180.jpg

    很多新学C语言的童鞋在用到动态内存分配的时候,对选择哪种分配函数及其有何区别搞不清楚,那么下文就认真的讲讲它们的种种。

    (1)C语言的内存分配方式

    • 从静态存储区域分配
      这些在程序编译的时候就已经分配好,且在程序的整个运行期间都固定不变。

    使用这种方式分配内存空间的数据主要包括:
    代码段(DATA Section)的程序自身语句文本(包括嵌在代码里的字符串常量),已经初始化的全局变量静态变量

    .BSS段的未初始化的全局变量

    • 在栈stack上分配

    这种方式由系统自动分配,函数退出时也由系统自动释放。

    使用这种方式分配内存空间的数据主要包括:
    本地变量函数参数

    • 从堆heap上分配,亦称动态内存分配

    程序在运行的时候用malloc类或new动态申请的内存,由用户自己负责用free或delete释放。动态内存的生存期由用户决定,使用非常灵活,但问题也最多。

    使用这种方式分配内存空间的数据主要包括:
    自定义输入缓存用于接收用户输入数据的变量(数组、结构体等)

    (2)跟内存申请相关的函数

    void* malloc(size_t size)

    作用:从堆中分配size个字节的空间,成功则返回空间首地址,失败则返回空指针。它的声明位于stdlib.h头文件中。

    我们在编程中必须注意分配失败的情况,以使程序更加健壮和完备。所以一般会对其进行包装:

            void *
    xmalloc (size_t size)
    {
        void *value = malloc (size);
        if (value == 0)
            fatal ("virtual memory exhausted");
        return value;
    }
    
          

    同时,由于它并没有对分配的空间进行任何操作,因此基本上malloc之后,需要调用函数memset来初始化。

            struct foo *ptr;
    ...
    ptr = (struct foo *) malloc (sizeof (struct foo));
    if (ptr == 0) 
        abort ();
    memset (ptr, 0, sizeof (struct foo));
    
          

    void * calloc (size_t count, size_t eltsize)

    作用:从堆中分配size个字节的已经清零的空间,成功则返回空间首地址,失败则返回空指针。它的声明位于stdlib.h头文件中。

    它的实现等同于:

            void *
    calloc (size_t count, size_t eltsize)
    {
        size_t size = count * eltsize;
        void *value = malloc (size);
        if (value != 0)
            memset (value, 0, size);
        return value;
    }
    
          

    void * realloc (void *ptr, size_t newsize)

    作用:用来对之前申请的动态内存重新进行分配大小(扩容或缩小)。

    参数解释:ptr必须为之前通过malloc或calloc等函数申请的动态内存首地址;newsize为你现在需要的大小。

    注意事项:
    1 如果是扩容,它不能保证后加的空间一定是接在原来申请的内存空间之后的,因为有可能其之后的空间已经被使用了。此时系统会找一块大小符合你要求的连续空间,并同时把原来空间内容复制到新空间,最后再释放原空间。

    2 如果扩容失败,则原空间内容不受影响。

    3 如果参数ptr为空,则其动作同malloc。

    但是当我们使用时,为了程序的健壮性和完备性,在使用时我们需要包装一下:

            void *
    xrealloc (void *ptr, size_t size)
    {
        void *value = realloc (ptr, size);
        if (value == 0)
            fatal ("Virtual memory exhausted");
        else
            return value;
    
          

    void * reallocarray (void *ptr, size_t nmemb, size_t size)

    该函数作用及各参数同realloc,唯一的不同是当发生乘法溢出时,会进行错误提示。

    void * aligned_alloc (size_t alignment, size_t size)

    作用:函数分配一个地址alignment对齐的大小为size的内存空间。

    参数解释:alignment代表地址对齐参数,必须为2的倍数,且size也必须是alignment的倍数。
    如果分配成功则返回内存首地址,否则返回空,同时依据错误原因设置错误代码errno为ENOMEN或EINVAL

  • 相关阅读:
    BZOJ 1040 (ZJOI 2008) 骑士
    BZOJ 1037 (ZJOI 2008) 生日聚会
    ZJOI 2006 物流运输 bzoj1003
    ZJOI 2006 物流运输 bzoj1003
    NOI2001 炮兵阵地 洛谷2704
    NOI2001 炮兵阵地 洛谷2704
    JLOI 2013 卡牌游戏 bzoj3191
    JLOI 2013 卡牌游戏 bzoj3191
    Noip 2012 day2t1 同余方程
    bzoj 1191 [HNOI2006]超级英雄Hero——二分图匹配
  • 原文地址:https://www.cnblogs.com/leon1124/p/14039772.html
Copyright © 2011-2022 走看看