动态内存申请之malloc( ) 、calloc( ) 、realloc( )(C语言)


动态内存申请之malloc( )、calloc( )、realloc( )

1.动态内存申请方式

1.1 引入

学习字符数组的时候,我们知道可以申请指定大小的内存空间,但是有一个问题,申请完毕后,必须要到函数结束这段内存空间才会被释放。
那么如何做到随时申请,随时释放内存空间呢?
这个时候需要利用动态内存申请方式,ANSI C中标准库stdlib.hmalloc()calloc()realloc()提供标准动态申请函数

1.2 malloc( )

函数原型void * malloc(unsigned int size);
在内存的动态存储区中分配一个长度为size的连续空间
函数返回值是一个无类指针,方便后期强制类型转换

代码部分:

#include 
#include 
#include 

int main ()
{
    char *ptr = (char *) malloc (15 * sizeof (char));
    if (NULL == ptr)
    {
        printf ("内存申请失败");
        return -1;
    }    
    strcpy (ptr, "hello world");
    printf ("%s\n", ptr);
    free (ptr);
    return 0;
}

验证部分:

注意:C语言对于指针越界操作不做检查,全靠程序员自己控制。尽量不要指针越界操作,否则会出现未知结果

提示:malloc()申请的空间里面的值是随机的,因此我们使用前需要进行初始化。例如memset (ptr, 0, sizeof (ptr))

1.3 calloc( )

如果要申请超过unsigned int size大小空间,那么malloc()就不适用了。
这时,calloc()就能上场了。

函数原型:void * calloc(unsigned n,unsigned size);
在内存的动态存储区中分配n个长度为size的连续空间,这个空间比较大

提示:calloc()申请的空间里面的值是自动初始化为0,我们可以直接使用,无需再次初始化

1.4 realloc( )

如何发现前面malloc()或calloc()申请空间小了,想扩大申请的连续空间大小,怎么办?
这是,realloc()可以解决问题

函数原型:void * realloc(void *p,unsigned int size);
使用realloc()的前提条件,malloc()或calloc()申请过内存空间

代码部分:

#include 
#include 
#include 

int main ()
{
        char *ptr = (char *)malloc (15 * sizeof (char));
        if (NULL == ptr)
        {
                printf ("failure\n");
                return -1;
        }
        printf ("ptr's addr:%p\n", ptr);
        strcpy (ptr, "hello world! ");
        printf ("%s\n", ptr);
        char *point = (char *) realloc (ptr, 50 * sizeof (char));
        if (NULL == point)
        {
                printf ("failure\n");
                return -2;
        }
        printf ("point's addr:%p\n", point);
        strcat (point, "welcome to China");
        printf ("%s\n", point);
        if (point == ptr)
                ptr = point;
        free (ptr);
        return 0;
}

验证部分:

注意:realloc()移动malloc()或calloc()空间数据,并返回一个无类指针。realloc()更改内存后,指针ptr和指针point指向同一块内存空间

验证molloc()返回指针和realloc()返回指针指向同一块内存空间

代码如下:

#include 
#include 
#include 

int main(void)
{
    char *p = malloc(5);
    if (NULL == p)
    {
        printf ("内存申请失败\n");
        return -1;
    }
    strcpy (p, "hello world");
    printf ("指针p指向内存空间内容:%s\n", p);
    printf ("指针p的值:%p\n", p);
    char *q = realloc(p, 4096);
    if (NULL == q)
    {
        printf ("内存申请失败\n");
        return -2;
    }
    printf ("指针q指向内存空间内容:%s\n", q);
    strcat (q, " welcome to China");
    printf ("操作指针q后,指针q指向的内存空间内容:%s\n", q);
    printf ("realloc()并操作指针q后,指针p指向内存空间内容:%s\n", p);
    printf ("指针q的值:%p\n", q);
    if (p == q)
      p = q;
    free(p);
    return 0;
}

验证结果:

2.释放动态内存

动态申请内存空间后,一般都要释放内存空间。如果不释放内存空间,则申请内存空间一直存在,反复申请空间,最后会导致内存资源耗尽,也会造成内存泄漏

函数原型: void free(void * p);