一、动态内存开辟的引入
在栈上开辟固定的内存空间。
int main()
{
int i = 0;//在栈空间开辟四个字节
char arr[10] = { 0 };//在栈空间上开辟10个连续空间
return 0;
}
特点:
1. 空间开辟大小是固定的。
2. 数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。
3. 但对于有些问题,有时候我们需要的空间大小在程序运行的时候才能知道,那数组的编译 时开辟空间的方式就不能满足了。 这时候就只能试试动态存开辟。
二、动态内存函数介绍。
1.malloc和free(附加calloc函数)
(1)malloc 函数向内存申请一块连续可用的空间:
void* malloc (size_t size);
如果开辟成功,则返回一个指向开辟好空间的指针。
如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。
(2)free 函数一般和 malloc 函数成对使用,free用来释放malloc 向内存申请的空间:
void free (void* ptr);
如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
如果参数 ptr 是NULL指针,则函数什么事都不做。
(3)malloc 函数与 free函数的使用:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int num = 0;
scanf("%d", &num);
int *ptr = NULL;
ptr = (int*)malloc(num*sizeof(int));//ptr指向malloc开辟的内存块上
if (ptr != NULL)
{
int i = 0;
for (i = 0; i < num; i++)
{
*(ptr + 1) = 0;
}
}
free(ptr); 使用完,free释放malloc的申请的内存空间
ptr = NULL;
return 0;
}
(4)calloc函数:
void* calloc (size_t num, size_t size);
函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *p = (int*)calloc(6,sizeof(int));
if (p != NULL)
{
int i = 0;
for (i = 0; i < 6; i++)
{
*(p + 1) = 6;
}
}
free(p);
p = NULL;
return 0;
}
内存块:
2.realloc函数使用:
(1)当申请的内存空间不足或多于的情况时,利用realloc函数将内存的大小进行调整,所以realloc函数可以进行内存大小的调整:
void* realloc (void* ptr, size_t size);
ptr 是要调整的内存地址
size 调整之后新大小
返回值为调整之后的内存起始位置。
这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间.
realloc在调整内存空间的是存在两种情况:
情况1:原有空间之后有足够大的空间
情况2:原有空间之后没有足够大的空间
当遇到情况一的时候,直接在元内存后面追加内存。
当遇到情况二的时候,:在堆空间上另找一个合适大小的连续空间来使 用。这样函数返回的是一个新的内存地址,原来内存中的数据移动到新的空间。
三、常见的动态内存的错误。
1.对NULL指针的解引用操作
int main()
{
int *ptr;
ptr = (int*)malloc(sizeof(int)* 4);
//*ptr = 20;//未判断ptr是否为空,或是判断malloc是否申请内存成功
if (ptr != NULL)
{
*ptr = 20;
}
return 0;
}
2.动态开辟的内存忘记释放(内存泄漏)
忘记使用free释放自主开辟的内存空间。
3.对开辟的内存空间越界访问
int main()
{
int *ptr = (int*)malloc(sizeof(int)* 10);
if (ptr != NULL)
{
int i = 0;
for (i = 0; i <= 10; ++i)//当i= 10,越界访问。
{
*(ptr + 1) = 1;
}
}
free(ptr);
ptr = NULL;
return 0;
system("pause");
}
4.对非动态开辟的空间进行free函数释放。
5.对同一块空间多次进行free函数释放。
忘记释放不再使用的动态开辟的空间会造成内存泄漏。 切记: 动态开辟的空间一定要释放,并且正确释放
所以,掌握好动态内存开辟常见的错误对于使用malloc,calloc,realloc以及free函数有很大帮助,希望可以帮到大家。