C语言中的malloc()和free()

C语言中经常会用到动态内存分配,也会提到内存泄漏等知识点。本文主要介绍共4个知识点

					1.介绍动态内存malloc()和free()函数的使用
					
					2.介绍内存泄漏的概念
					
					3.动态内存分配和变长数组的区别
					
					4.介绍程序将内存分为哪几个部分
  • 分配内存:malloc() 和 free()

    回忆一下,静态数据在程序载入内存时分配,而自动数据在程序运行块时分配内存,并在程序离开块时销毁。
    c能做的不止于此,可以在程序运行的时候分配更多的内存,主要的工具是**malloc()**函数。该函数接受一个参数:所需的内存字节数。

    double * ptd;
    ptd = (double *)malloc(30 * sizeof(double));
    

    以上代码为30个double类型的值请求内存空间,并设置ptd指向该位置。

    现在,我们有三种创建数组的方法

    1. 声明数组时,用常量表达式表示数组的维度,用数组名访问数组的元素。可以使用静态内存或自动内存来创建。
    2. 声明变长数组时 ,用变量表达式表示数组的维度。用数组名访问数组的元素,只能在自动内存中来创建。
    3. 声明一个指针,调用malloc(),将其返回值赋值给指针,使用指针访问数组的元素。该指针可以是静态的也可以是动态的。

    使用第二种和第三种方法可以创建动态数组。这种数组和普通数组不同,可以在程序运行时选择数组的大小和分配内存。例如:ptd = (double *)malloc(n * sizeof(double));

    通常。malloc()要与free()配套使用。free()函数的参数是之前malloc()返回的地址,该函数释放之前malloc()分配的内存。因此,动态分配内存的存储期是从调用malloc()分配内存,到调用free()释放内存为止。malloc()和free()的函数原型都在stdlib.h头文件中。值得一提:malloc()可能分配不到所需的内存,这种情况下,函数返回空指针。

    提问:假如忘记使用free()会有啥影响?内存会被一直占用吗?

    回答:不会有影响,程序处于运行状态,内存就被一直占用。程序一退出,内存就被释放了。但是如果程序一直处于运行状态,忘记释放内存就会造成内存泄漏。

  • 内存泄漏

    什么是内存泄漏呢?

    int main()
    {
    	double glad[2000];
        int i;
        ...
        for(i=0;i<1000;i++)
            gobble(glad,2000);
        ...
    }
    void gobble(double ar[],int n)
    {
    	double * temp = (double *)malloc(n*sizeof(double));
        //free(temp) 假设忘记使用free释放内存
    }
    

    第一次调用gobble()时,他创建了指针temp,并调用了malloc分配了16000字节的内存。可是当函数结束时,作为自动变量的temp自动消失,但是他所指向的16000字节的内存依然存在。由于temp被销毁,所以无法访问这块内存,他也不能被重复使用。因为代码没有调用free().如果在程序退出之前,循环需要执行1000次,所以在循环结束前有1600万字节被占用,这类问题就被称作为内存泄漏。

  • calloc()函数

    分配内存还可以使用calloc()函数,他的用法和malloc()类似

  long * newmem;

  newmem = (long *)calloc(100 , sizeof(long));

  free(newmem);//对于calloc()函数,free()也可以释放内存。
  • 动态内存分配和变长数组

    俩者都可以用于创建在运行时确定大小的数组,但是而招人有什么区别呢?

    1. 变长数组是自动储存类型,所以在离开所定义的块时自动释放内存。而动态内存分配则需要free()来释放。

    2. 变长数组只能局限于在某一个函数进行访问,而动态内存分配不必局限于在一个函数访问。并且free()的参数可以和malloc()的指针变量不同,只要俩个指针存储相同的地址就行。

    3. 创建二维数组:

      变长数组

      ​ int n=3,m=4;

      ​ int ar2[n] [m];

      ​ int (*p2) [4];//C99之前的写法

      ​ int (*p2) [m];

      动态内存分配

      ​ int n=3,m=4;

      ​ p3= (int () [4]) malloc(n * 4 * sizeof(int)); //n4数组

      ​ p3= (int () [m]) malloc(n * 4 * sizeof(int));//nm数组必须支持变长数组

  • 存储类别和动态内存分配

    可以认为程序把他可用的内存分为3部分:一部分供具有外部链接、内部链接、无链接的静态变量使用。一部分供自动变量使用,一部分供动态内存分配使用,他们分别对应三种存储类型:普通内存、栈、堆。当然还有一个寄存器存储类型。

    1.静态存储类别所用的内存数量在编译时确定,在程序结束时被销毁。

    2.自动存储类别的变量在程序进入块时存在,在程序离开块时消失。这部分内存通常作为栈来处理,这意味着新创建的变量按顺序加入内存,然后以相反的顺序销毁。

    3.动态分配的内存在调用malloc()或相关的函数时存在,在调用free()后释放。这部分内存主要由程序员管理,而不是一套规则。这部分内存通常被称为堆或自由内存。通常使用堆内存比使用栈内存慢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值