动态内存函数详解
- malloc
- 一、malloc的简介
- 1.malloc函数的定义:
- 2.参数:
- 3.返回值:
- 4.功能:
- 二、malloc函数的使用
- free函数
- free函数的简介
- free函数使用注意事项
- calloc
- calloc函数的简介
- 二、calloc函数的使用
- calloc函数的注意事项
- realloc函数
- 一、realloc函数的简介
- 二、realloc使用
- 三、realloc函数的注意事项
- 四、关系
malloc
头文件:stdlib.h
一、malloc的简介
1.malloc函数的定义:
void* malloc (size_t size);
2.参数:
size
: 内存块的大小(以字节为单位
)。size是无符号整型。size_t
3.返回值:
1)如果开辟成功,则返回一个指向开辟好空间的指针。
2)如果开辟失败,则返回一个NULL指针
,因此malloc的返回值一定要做检查。
3)返回值的类型是 void*
,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。
4)如果参数 size 为0,malloc的行为是标准是未定义的,取决于编译器。
4.功能:
向内存申请一块连续可用的空间,并返回指向这块空间的指针。单位:字节
二、malloc函数的使用
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = (int*)malloc(40);//申请了40个字节,强转成int*型
if (p == NULL)//判断是否开辟成功
{
perror(malloc);
return 1;
}
//打印开辟空间,检验是否开辟完成
int i = 0;
for (i = 0;i < 10; i++)
{
printf("%p\n", (p + i));
}
free(p);
p=NULL;
return 0;
}
运行截图:
可以看到,我们已经开辟了十个整形的空间。
free函数
头文件:stdlib.h
free函数的简介
void free (void* ptr);
参数:指向先前分配的内存块的指针
如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
如果参数 ptr 是NULL指针,则函数什么事都不做。
没有返回值
free函数使用注意事项
如果开辟的空间使用完了,则应该使用free函数将p所指向的空间释放掉。
注意,p是指针变量,有自己存储空间和内容,我们free释放的只是p指向的那块空间,p并没释放,他仍然指向那块空间,所以需要手动给p=NULL。
calloc
头文件:stdlib.h
calloc函数的简介
void* calloc (size_t num, size_t size);
参数:
1.num:要分配的元素数
2.size:要分配的元素类型
返回值
1.成功时,指向函数分配的内存块的指针。
(此指针的类型始终为 ,可以强制转换为所需类型的数据指针,以便可取消引用。)
2…如果函数无法分配请求的内存块,则返回空指针。void*
功能:
–>.函数的功能是为 num
个大小为 size
的元素开辟一块空间,并且把空间的每个字节初始化为0
。
区别:与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
二、calloc函数的使用
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = (int*)calloc(10,sizeof(int));//申请了40个字节,强转成int*型
if (p == NULL)//判断是否开辟成功
{
perror(malloc);
return 1;
}
//打印开辟空间,检验是否开辟完成
int i = 0;
for (i = 0;i < 10; i++)
{
printf("%p\n", (p + i));
}
free(p);
p = NULL;
}
calloc函数的注意事项
1.不能申请开辟空间太大
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = (int*)calloc(INT_MAX,sizeof(int));//申请了40个字节,强转成int*型
if (p == NULL)//判断是否开辟成功
{
perror(calloc);
return 1;
}
//打印开辟空间,检验是否开辟完成
int i = 0;
for (i = 0;i < 10; i++)
{
printf("%p\n", (p + i));
}
free(p);
p = NULL;
}
显示错误:Not enough space
realloc函数
一、realloc函数的简介
void* realloc (void* ptr, size_t size);
1.参数
ptr
:指向先前分配有 、 或 的内存块的指针。
或者,这可以是一个空指针,在这种情况下,将分配一个新块(就像被调用一样)
size
:内存块的新大小(以字节为单位)。是无符号整型。size_t
(size=原来+新增加)
2.返回值:指向重新分配的内存块的指针,该内存块可能与新位置相同,也可能是新位置
3.功能:(1)重新分配内存块,更改指向的内存块的大小。
(2).如果函数无法分配请求的内存块,则返回空指针,并且不会释放参数指向的内存块
(3).有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合适的内存,我们一定会对内存的大小做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小的调整。
二、realloc使用
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = (int*)calloc(10,sizeof(int));//申请了40个字节,强转成int*型
if (p == NULL)//判断是否开辟成功
{
perror(calloc);
return 1;
}
//打印开辟空间,检验是否开辟完成
int i = 0;
for (i = 0;i < 10; i++)
{
p[i]=i+1;
}
int* ptr = (int*)realloc(p, 80);
if (ptr != NULL)
{
p = ptr;
}
else
{
perror(realloc);
return 1;//结束
}
for (i = 0; i < 20; i++)
{
printf("%d\n", p[i]);
}
free(p);
p = NULL;
}
三、realloc函数的注意事项
用上面代码为例:
1.使用realloc给p扩容后,不能直接用p来接收。因为一旦扩容失败,将会返回NULL,那么p所指向的内容就会直接找不到了,造成内存泄漏。应该使用一个新指针ptr来接收,判断是否扩容成功后,再将ptr指向p即可。如下:
2.free(p);就相当也释放了ptr指针。因为ptr指向了p指针。
(1)扩容成功情况
int* ptr = (int*)realloc(p, 80);
if (ptr != NULL)
{
p = ptr;
}
可以看到ptr和p的值相同,说明它们指向相同。即扩容成功。
(2)扩容失败情况
我们这扩容到8000000000000直接则失败。
可以见到ptr指针指向空,也说明了realloc函数开辟失败返回值是NULL。
四、关系
void* realloc (void* ptr, size_t size);
1.realloc函数的参数,如果ptr传空指针,就相当于malloc函数。