1.堆与栈
1.1 堆
在内存的全部存储空间中,用于程序动态分配和释放的内存块称为自由存储空间,通常也称之为堆。在c程序中,是用malloc函数和free函数来从堆中动态地分配和释放内存。
1.2 栈
程序不会像处理堆那样在栈中显示地分配内存,当程序调用函数和声明局部变量时,系统将自动分配内存。
2.分配内存函数(malloc和calloc)
2.1 malloc函数
malloc函数原型如下:
void *malloc
(unsigned int size);
在stdlib.h头文件中包含该函数,其作用是在内存中动态地分配一块size大小的内存空间。malloc函数会返回一个指针,该指针指向分配的内存空间;如果出现错误,则返回NULL。
注意:使用malloc函数分配的内存空间是在堆中,而不是在栈中。因此,在使用完这块内存之后一定要将其释放掉。释放内存空间使用的函数是free函数。
例如:使用该函数分配一个整型内存空间:
int *plnt;
plnt=(int *)malloc(sizeof(int));
2.2calloc函数
calloc函数包含在头文件stdlib.h中,其功能是在内存中动态分配n个长度为size的连续内存空间数组。calloc函数会返回一个指针,该指针指向动态分配的连续内存空间地址。当分配空间错误时,返回NULL。
calloc函数原型如下:
void *calloc(unsigned n,unsigned size);
例如:使用该函数分配一个整型数组内存空间
int *pArray;
pArray=(int *)calloc(3,sizeof(int));
3.修改已分配内存(realloc)
realloc函数包含在头文件stdlib.h中,其功能是改变ptr指针指向的空间大小为size大小。设定的size大小可以是任意的,也就是说可以比原来的数值大,也可以比原来的数值小。返回值是一个指向新地址的指针,如果出现错误则返回NULL。
其函数的原型如下:
void *realloc(void *ptr,size_t size);
例如:将一个分配的实型的空间大小改为整型大小。
fDouble=(double *)malloc(sizeof(double));
ilnt=realloc(fDouble,sizeof(int));
其中fDouble指向分配的实型空间,之后使用realloc函数改变fDouble所指向空间的大小,其大小设置为整型,然后将改变后的内存空间地址返回值赋给ilnt整型指针。
4.释放内存(free)
free函数的功能是释放指针ptr指向的内存区,使其能被其他变量使用。
void free(void *ptr);
/*为具有3个元素的数组分配内存*/
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *p;
int i;
p=(int *)malloc(sizeof(int[3])); /*分配3个整型的内存空间*/
for(i=0;i<3;i++)
{
*(p+i)=10*(1+i); /*给数组赋值*/
printf("%d\n",*(p+i));
}
return 0;
}
/*为二维数组动态分配内存并释放*/
#include<stdio.h>
#include<stdlib.h>
int main()
{
int **pArray2; /*二维数组指针*/
int iIndex1,iIndex2; /*循环控制变量*/
pArray2=(int**)malloc(sizeof(int*[3])); /*指向指针的指针*/
for(iIndex1=0;iIndex1<3;iIndex1++)
{
*(pArray2+iIndex1)=(int *)malloc(sizeof(int[3]));
for(iIndex2=0;iIndex2<3;iIndex2++)
{
*(*(pArray2+iIndex1)+iIndex2)=iIndex1+iIndex2;
}
}
/*输出二维数组中的数据内容*/
for(iIndex1=0;iIndex1<3;iIndex1++)
{
for(iIndex2=0;iIndex2<3;iIndex2++)
{
printf("%d\t",*(*(pArray2+iIndex1)+iIndex2));
}
printf("\n");
}
return 0;
}
什么是"内存泄露"
当定义了一个指针时,立即要为这个指针分配一个内存空间,这只是防止了野指针的产生,当使用完毕后应立即释放其所占空间。如果没有及时释放指针所占用的内存空间,而下次再用这个指针时又为其分配内存空间,再使用,再分配。这样次数一多,内存空间就被慢慢消耗掉了。因此,像这种现象称为内存泄露。
内存耗尽了怎么办
解决内存耗尽问题有三种方法:
1.判断指针是否为NULL,如果是,则马上使用return语句终止本函数。
2.判断指针是否为NULL,如果是,则用exit(1)终止整个程序的运行。
3.为new函数和malloc函数设置异常处理函数。
c语言中常见的内存管理错误有以下4种
1.分配了一块内存空间,引用了未经初始化的内容。
2.释放了一块内存空间,但是却继续引用其内容。
3.分配了一块内存空间,但是没有保存指向该内存的指针,造成无法对此指针进行引用或者释放,这块内存空间也成为了系统中的“垃圾”内存,从而浪费了内存资源。
4.内存的读写操作超越了所分配的内存空间的边界。