动态内存管理
一、为什么要存在动态内存?
1、申请的动态内存具有灵活性,比如在栈上申请一个数组必须要确定数组的大小,而是使用多少,开辟多少。节省空间
2、申请的内存比栈上大的多。比如说你要在栈上申请一百万字节,可能就会越界,而申请动态内存可以申请上亿字节。
二、申请的动态内存在哪里?
答:申请的动态内存在堆上。
三、如何申请动态内存?
使用malloc 函数、calloc函数和realloc函数。
(1)molloc 函数
void *malloc(size_t size );
malloc 函数返回值是void *(申请到的动态内存的起始位置)。它的参数是size_t(无符号型),size 是申请的大小。
如果申请成功,返回申请到的动态内存的起始位置,但不初始化。申请失败返回NULL。
如果申请成功,使用这些内存之后,必须使用free函数释放,否则会发生内存泄漏
代码示列
int main() { int* ptr = NULL; ptr =(int*) malloc(10*sizeof(int)); if (ptr != NULL)//判断是否申请成功,如果,申请成功在使用 { int i = 0; for (i = 0; i < 10; i++) { *(ptr+i) = i; printf("%d ",i); } } free(ptr);//一定不要忘了释放。 return 0; }
运行结果如下:
(2)calloc函数
void *calloc(size_t num,size_t size)
返回值和malloc函数一样,num和size代表申请num个大小位size的空间。
它的功能是申请num个大小位size的空间,并全部初始化为0;
举个列子
int main()
{
int* p = (int*)calloc(10, sizeof(int));
for (int i = 0; i < 10; i++)
{
printf("%d ", p[i]);
}
free(p);
return 0;
}
结果如下:
(3)realloc函数
认识realloc函数之前先了解一个概念,就是在堆上申请动态内存,内存空间必须是连续的,因为它只能整体申请整体释放。
void *realloc(void *ptr,size_t size)
realloc函数是对已经申请的动态内存大小进行修改,既可以改打,也可以改小。
ptr是需要改的起始位置,size是改变后的大小。
在调整原来大小的基础上,会将原来的内存中的数据也移到新的内存中。
举个列子:
#include<stdio.h>
#include<stdlib.h>
#pragma warning(disable:4996)
int main()
{
int* ptr = (int*)malloc(100);
if (ptr != NULL)
{
int i = 0;
for (i = 0; i < 10; i++)
{
*(ptr+i) = i;
printf("%d ",i);
}
}
else
{
exit(EXIT_FAILURE);//exit程序退出函数
}
//ptr= (int*)realloc(ptr, 100000);这样不行,如果申请失败,之前ptr的数据也会消失
int* p = NULL;
p = (int*)realloc(ptr, 100000);
if (p != NULL)
{
ptr = p;
}
free(ptr);
return 0;
}