衡水需要做网站的公司,wordpress多个标签页,沧州市宇通网站建设公司,巴彦淖尔 网站建设目录
一.为什么存在动态内存管理
二.动态内存函数的介绍
1. malloc函数#xff08;memory alloc 内存开辟#xff09;
函数介绍#xff1a;
malloc函数使用举例代码#xff1a;
2.free#xff08;释放#xff09;
函数介绍#xff1a;
代码的示例#xff1a… 目录
一.为什么存在动态内存管理
二.动态内存函数的介绍
1. malloc函数memory alloc 内存开辟
函数介绍
malloc函数使用举例代码
2.free释放
函数介绍
代码的示例
3.calloc
函数介绍
代码示例
运行结果
4.realloc
函数介绍
使用示例代码
常见的动态内存管理的错误
1.对NULL指针进行解引用操作
2.对动态开辟的空间越界访问
3.对非动态开辟的空间使用free
4.使用free释放一块动态开辟的内存中的一部分
5.对同一块内存多次释放
6.动态内存开辟忘记释放造成内存泄漏 一.为什么存在动态内存管理
我们常见的内存开辟方式
int a 20; //在栈空间上开辟四个字节
int arr[10] { 0 }; //在栈空间上开辟40个字节
但是上的开辟空间方式有两个特点
1.开辟的空间的大小是固定的
2.数组在申明的时候必须指定固定的长度它所需的内存在编译时分配有可能用不完造成浪费也有可能后期不够用
但是下在我们实际所需求中不仅仅是上面的两种情况有时候我们需要的空间大小在程序运行时才知道那么上述方式开辟空间就不能够满足所以有了动态内存开辟。 二.动态内存函数的介绍
必备知识
内存大概的划分
栈区 主要存放局部变量形式参数等等
堆区 动态内存的开辟mallocfreecallocrealloc等等
静态区 全局变量静态变量等等 1. malloc函数memory alloc 内存开辟
函数介绍
void* mallocsize_t size
malloc函数可以向内存申请一块连续的空间并返回指向这块空间的指针
值得注意的是
1. 如果开辟成功将返回一个指向开辟好了的空间的指针
如果开辟失败将返回空指针NULL
所以在开辟后需要判断是否开辟成功检查返回值
2. 函数返回的是空指针malloc函数并不知道开辟空间的类型所以在使用的时候需要自己决定使用强制类型转换
3.如果size为0时malloc函数的行为是未定义的取决于编译器
4.malloc函数开辟的空间里面存放的是随机值下面代码可验证
5.malloc函数申请的空间当程序退出时还给操作系统当程序不退出时动态开辟的空间不会主动还给操作系统需要用free函数来释放
malloc函数使用举例代码
int main()
{int* p (int *)malloc(40); //这里需要的是int*类型的指针所以用强制类型转换为int*if (p NULL){perror(malloc); //判断是否开辟成功return 1;}int i 0;for (i 0; i 10; i){printf(%d\n,*(pi));}free(p);pNULL; //将p置为空指针不要让p成为野指针return 0;
}
运行结果
-842150451-842150451-842150451-842150451-842150451-842150451-842150451-842150451-842150451-842150451 2.free释放
函数介绍
void* free void* p
C语言提供的free函数是专门用来做动态内存的释放和回收的
free是用来释放动态开辟的内存
1.如果void* p所指向的内存不是动态开辟的free函数的行为是未定义的
2.如果void* p所指向的是NULL空指针则free函数什么都不做 代码的示例
int main()
{int* p (int *)malloc(40); //这里需要的是int*类型的指针所以用强制类型转换为int*if (p NULL){perror(malloc); //判断是否开辟成功return 1;}int i 0;for (i 0; i 10; i){printf(%d\n,*(pi));}free(p); //使用完该空间后释放pNULL; //将p置为空指针不要让p成为野指针return 0;
} 3.calloc
函数介绍
void* calloc size_t num , size_t size
功能是为num个大小为size的元素开辟一块空间并吃初始化为0
与malloc函数类似只是会将开辟的空间内容初始化为0 代码示例
int main()
{int* p (int* )calloc(40,sizeof(int));if (p NULL){perror(calloc);return 1;}int i 0;for (i 0; i 10; i){printf(%d ,*(pi));}free(p);p NULL;return 0;
} 运行结果
0 0 0 0 0 0 0 0 0 0 4.realloc
realloc函数可以让内存管理更加灵活
函数介绍
viod* realloc void* ptrsize_t size
realloc函数可以调整我们申请的空间的大小
其中ptr是要调整的内存地址
size是调整之后的大小
返回值是为调整之后的内存起始位置
当void* ptr 为一个空指针时功能和malloc一样
值得注意的是这个函数调整之后可能将原来内存中的数据移动到新的空间
分为两种情况
1.原有空间的后面有足够大的空间时即原有空间后面的剩余空间有所需增加空间那么大就直接在原有空间后面开辟并且返回指向原来空间的指针
2.当原有的空间后面没有足够大的空间来增加空间则需要重新找一个空间开辟并且将原有空间的内容复制过去然后释放旧的空间的内存返回新的地址 使用示例代码
int main()
{int* p (int* )malloc(40);if (p NULL){perror(malloc);return 1;}int i 0;for (i 0; i 10; i){p[i] i1;}int* ret realloc(p,80);{if (ret NULL){perror(realloc);return 1;}else{p ret;}}for (i 0; i 20; i){printf(%d ,*(pi));}free(p);p NULL;return 0;
} 运行结果
1 2 3 4 5 6 7 8 9 10 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 常见的动态内存管理的错误 1.对NULL指针进行解引用操作 void test { int *p int *mallocINT_MAX; *p 20; //如果p是空指针就有问题 free(p); }
当用内存函数开辟好空间后不检查是否开辟成功就直接使用
2.对动态开辟的空间越界访问
int* p (int*)malloc(40);
int i 0;
for(i0;i12;i) // i10,11,就越界访问了
{ printf(%d ,*(pi));
}
3.对非动态开辟的空间使用free
int a 10;
int* p a;
free(p); // 错误的
4.使用free释放一块动态开辟的内存中的一部分
int* p(int *)malloc(40);
p;
free(p); //p后已经不是指向的原开辟的内存而是指向的一部分
5.对同一块内存多次释放
int* p (int*)malloc(40);
free(p);
free(p);
6.动态内存开辟忘记释放造成内存泄漏
void test
{ int * p (int*)mmalloc(40) if(NULL!p) { *p20; }
} //使用完后忘记释放出函数p销毁但是40个字节的空间还在
int main()
{ test(); while(1); //死循环程序不结束40个字节永远用不到
} 作者GOXXT 专注分享在学习道路上的知识笔记