赞
踩
C语言中经常会用到动态内存分配,也会提到内存泄漏等知识点。本文主要介绍共4个知识点
1.介绍动态内存malloc()和free()函数的使用
2.介绍内存泄漏的概念
3.动态内存分配和变长数组的区别
4.介绍程序将内存分为哪几个部分
回忆一下,静态数据在程序载入内存时分配,而自动数据在程序运行块时分配内存,并在程序离开块时销毁。
c能做的不止于此,可以在程序运行的时候分配更多的内存,主要的工具是**malloc()**函数。该函数接受一个参数:所需的内存字节数。
double * ptd;
ptd = (double *)malloc(30 * sizeof(double));
以上代码为30个double类型的值请求内存空间,并设置ptd指向该位置。
现在,我们有三种创建数组的方法
使用第二种和第三种方法可以创建动态数组。这种数组和普通数组不同,可以在程序运行时选择数组的大小和分配内存。例如: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()也可以释放内存。
俩者都可以用于创建在运行时确定大小的数组,但是而招人有什么区别呢?
变长数组是自动储存类型,所以在离开所定义的块时自动释放内存。而动态内存分配则需要free()来释放。
变长数组只能局限于在某一个函数进行访问,而动态内存分配不必局限于在一个函数访问。并且free()的参数可以和malloc()的指针变量不同,只要俩个指针存储相同的地址就行。
创建二维数组:
变长数组
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()后释放。这部分内存主要由程序员管理,而不是一套规则。这部分内存通常被称为堆或自由内存。通常使用堆内存比使用栈内存慢。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。