动态分配那些事儿

作者: Leon_Geo | 来源:发表于2019-02-09 08:38 被阅读2次

    当编写程序时,偶尔会不确定数组的大小(包括存储字符串的数组)。较为方便的做法是等到程序运行时再来确定数组的实际大小。
    在标准C中,提供了3个库函数:malloc(),calloc()和realloc()。那么他们有什么区别,分别用在什么场合呢?

    malloc()函数

    函数原型:
    void * malloc(size_t num_byte)
    参数介绍:

    • 一般来说,如果申请成功会它返回一个无类型(通用)指针,使用者需要通过强制类型转换将其转换为你需要的类型。如果申请失败,函数返回空指针。
    • num_byte为你申请的空间大小,它固定以8位单字节为单位。在实际编程中,为了程序的可移植性,往往使用sizeof()运算符来计算申请的单个元素数据类型所占的字节大小。
    int *p;
    p = (int *)malloc( n * sizeof(int) );
    if ( NULL = p ){
        printf("malloc failed!");
        exit(EXIT_FAILURE);
    }
    ...
    

    -需要注意的是,它从内存的堆(heap)资源中分配空间,且不会对分配的内存资源进行初始化。

    calloc()函数

    函数原型:
    void *calloc(size_t n_memb,size_t size)
    参数介绍:
    -同malloc()函数,如果申请成功会它返回一个无类型(通用)指针,使用者需要通过强制类型转换将其转换为你需要的类型。如果申请失败,函数返回空指针。

    • n_memb为申请的元素个数,size为每个元素的所占字节大小。
    • 在分配了内存之后,会以对所有位清零的方式进行初始化。
    • 下例展示为n个整数的数组分配内存空间,并初始化数组元素为0。
    int *a;
    a = (int *)calloc( n*sizeof(int) );
    if(NULL=a){
    printf("mallocfailed!");
    exit(EXIT_FAILURE);
    }
    
    • 通过调用以1为第一个实参的方式,可以为任何类型的数据项分配已初始化为零的空间。

    realloc()函数

    一旦分配完了空间,稍后可能会发现空间过小或者过大。此时该函数可以调整原来空间的大小以适应新的要求。
    函数原型:
    void *realloc(void *ptr, size_t size)
    参数介绍:

    • ptr必须指向先前通过malloc()或calloc()或realloc()函数分配的空间指针。
    • size表示内存块的新尺寸,它可以大于或小于原尺寸。

    使用原则:

    • 它不会对扩展的内存块进行初始化。
    • 如果分配失败,返回空指针,且原数据块不受影响。
    • 如果ptr设置为空指针,行为同malloc()函数。
    • 如果size设置为0,行为同free()函数,即释放ptr所指空间资源。
    • 在扩大空间的情况下,realloc()会尽量在原地进行扩充,如果无法原地扩充(内存块后面的空间已经用于其他目的),它会在别处重新分配内存块,并把旧块中的数据复制过去。所以,在调用完该函数后,切记更新所有指向该内存块的指针变量。

    free()函数

    在讲解了空间分配函数后,不得不提的就是要及时!及时!及时!释放之前申请的空间。否则随着程序的运行,会产生大量内存垃圾(内存泄露),最后系统会因资源耗尽而嗝屁。
    函数原型:
    void free(void *ptr)
    参数介绍:

    • 使用它很容易,你只要把你之前申请的现在不需要的内存块指针传递给它就好了。
    p = malloc(...);
    ...
    free(p);
    
    • 虽然利用free()函数释放了p指向的内存空间,但p的值并没有改变。如果不把p及时及时及时指向空(NULL),会产生悬空指针,如果之后程序试图修改它指向的内存数据,会有程序崩溃等损失惨重的后果。

    相关文章

      网友评论

        本文标题:动态分配那些事儿

        本文链接:https://www.haomeiwen.com/subject/kdeasqtx.html