首先介绍内存的简单概念:
\内存主要分为三大区域,用于存放不同类型的变量:
栈区:存放临时的变量,例如局部变量,形参,也就是我们常用的开辟空间方法;
静态区:存放静态变量 (static 定义),全局变量;
堆区:使用动态内存开辟的主要区域;
C语言中参与动态内存分配的函数主要有: malloc calloc realloc free
mallocvoid *malloc( size_t size ); //malloc 函数的含义是:在 堆区 申请了 size 个 字节 的空间,最后以 void* 的类型返回已申请空间的首地址; //不会对申请的空间进行初始化;
一般在赋值过程将malloc开辟的空间转换成自己所需的指针类型,以便于维护。例如:
#includeint* p = (int*)malloc(50);//向内存申请50个字节,用int*类型维护; if( NULL == p) return; *p = 0;
如果开辟失败,则会返回空指针 NULL
free该函数主要是对向堆区申请的空间进行释放(将空间交还操作系统),其格式为:
void free( void *memblock ); // memblock是存放动态内存开辟的首地址的指针变量,函数无返回值
memblock存放的如果不是动态内存开辟的首地址(常规定义),free行为是未知的;
如果memblock存放的是NULL,free函数没有任何行为;
int* p = (int*)malloc(50); free(p); //在使用free函数后,p指向的空间已被归还,但仍然指向首地址, p = NULL; //所以在释放后一定要手动置空;calloc
void *calloc( size_t num, size_t size ); //calloc 函数会在 堆区 上申请一块连续的 num 个大小为 size 的空间,并将此空间上的值置为0(malloc不初始化) //返回申请空间的首地址;申请失败返回null;
其他使用方法与 malloc 相同
int* p = (int*) calloc(10, sizeof(int));
free(p);
p = NULL;
if( NULL == p)
printf("%sn",strerror(errno))
realloc
该增容函数在动态内存开辟中最为灵活,是动态内存开辟函数的**“主力”**
在使用动态内存的过程中,可以用该函数改变所申请内存空间的大小,提高内存利用;
void *realloc( void *memblock, size_t size ); memblock 变量存放的是指向之前开辟好的空间的首地址; realloc函数会将memblock指向空间的内容拷贝至新开辟的 大小为 size 个字节的空间中,并将此空间的首地址以 void* 类型的方式返回;
realloc 有两种开辟方法:
1. 当memblock 指向开辟的空间后面有足够的未被使用的空间时,realloc会在此空间之后开辟空间,返回的地址与memblock存放的地址相等;
2. 当memblock 指向开辟的空间后面没有有足够的未被使用的空间时,realloc会重新找一块空间,将memblock的数据拷贝过去,free掉memblock指向的空间,并将新的空间地址返回;
p = (int*)realloc(p, 30);
int* ptr = (int*)realloc(p, 40); if( ptr != NULL) p = ptr;
注意问题
-
动态空间的越界访问:如果需要增容空间,使用realloc,否则非法使用未开辟空间会造成未知错误;
-
非动态开辟的空间用free释放:常规定义的变量用free释放,程序会报错;
-
不能对存放已动态开辟的变量进行自加或自减操作,否则会导致使用free释放不完全,导致内存泄漏;
-
严禁对同一块空间进行过次free释放
-
动态内存开辟忘记释放(即内存泄漏):> 空间回收有两种方式:1. free释放 2. 程序结束退出,OS自动回收
内存泄漏:在写有关动态内存开辟函数时,忘记使用完释放,导致程序运行过程中,即使该空间未被该程序使用,其他程序也无法使用这片空间,造成空间浪费;如果特定程序一直在开辟空间而不回收,会导致内存慢慢好干,没有空间可用,导致程序崩溃。
void GetMemory(char* p) { p = (char*)malloc(100); } void Test(void) { char* str = NULL; GetMemory(str); strcpy(str, "hello world"); printf(str) }局部性原理:在使用某些数据的时候,接下来使用的数据大概率会是周围的数据,在使用内存的数据时,也会将周围数据连同使用的数据加载到缓存中。



