存在动态内存分配的原因
我们之前学到的内存开辟方式:
int c=10;
char ch[20]={5};
//在栈上开辟
但是之前的开辟空间的方式有两个特点:
- 空间开辟大小是固定的;
- 数组在申明的时候,必须指定数组的长度,它所需的内存在编译时分配。
栈区,堆区和静态区的分配情况:
动态内存函数的介绍
malloc
void* malloc(size_t size);
//size为开辟的字节数
头文件为stdlib.h
该函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。
- 如果开辟成功,返回一个指向开辟好空间的指针;反之若不成功,则返回一个NULL指针,所以malloc的返回值一定要做检查
free
void free(void* ptr);
free函数用来释放动态开辟的内存
- 如果参数ptr指向的空间不是动态开辟的,那free函数的行为是未定义的。
- 如果参数ptr是NULL指针,则函数什么事都不做。
动态内存的回收:
1.程序结束后,系统会自动回收。
2自动回收——free
例://free只释放动态内存 free(p);//手动释放动态开辟的内存 p=NULL;//防止p还记得,让其失忆 //malloc和free要成对出现
calloc
也能用来动态内存分配
void* calloc(size_t num,size_t size);
- 函数的功能为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0.
- 与函数malloc的区别只在于calloc会在返回地址之前把申请的空间每个字节初始化为0.
realloc
调节动态内存空间大小
void* realloc(void* memblock,size_t size);
//memblock为要调节的空间地址
//size要调节为多大
注:
当原有空间之后没有足够多的空间,扩展的方式是:在堆空间上另找一个适当大小的连续空间来使用,这样函数返回的是一个新的内存地址,记得要把返回值接收。
//扩大ptr,先定义个新的指针
int* p=NULL;
p=realloc(ptr,100);
if(p!=NULL)
{
ptr=p;
}
free(ptr);
常见的动态内存错误:
- 对NULL指针的解引用操作
- 对动态开辟空间的越界访问
- 对非动态开辟内存使用free释放
- 使用free释放一块动态开辟内存的一部分
- 对同一块动态内存多次释放
- 动态开辟内存忘记释放