目录
一、为什么存在动态内存分配
二、动态内存函数
malloc和free
calloc
realloc
一、为什么存在动态内存分配
之前我们学过的开辟空间的方式就是如下两种:
int main()
{
int a = 5;
char ch = 'b';
int arr[20] = { 0 };
}
以上的开辟内存的方式都是开辟好内存之后所开辟的内存是固定的,不能改变的,这种开辟方式不够灵活
C语言里面的动态开辟内存就解决了这个问题
在学习C语言的时候通常大致将内存划分为三部分:栈区,堆区,静态区
动态开辟内存就是在栈上面开辟的空间
二、动态内存函数
malloc和free
malloc函数原型
void *malloc( size_t size );
参数:size_t size,就是想要开辟多大一块空间(以字节为单位),类型为无符号整型
返回值:void*类型的指针,就是返回所开开辟的这块空间的起始地址,将来这块空间用来存什么类型的数据是不确定的,所以是void*类型;如果内存开辟失败,就返回空指针(NULL)
头文件:
如果参数size 为0,malloc的行为是标准是未定义的,取决于编译器
如下示例:
#include#include int main() { int* ps = (int*)malloc(100); if (ps == NULL) { perror("malloc:"); } else { for (int i = 0; i < 50; i++) { *(ps + i) = i; } for (int i = 0; i < 50; i++) { printf("%d ", *(ps + i)); } } return 0; }
分析:
因为我们想要用动态开辟的空间来存整型数据,所以就用整型指针来接受返回值,并且需要强制类型转换,然后用if语句来检验是否开辟成功,若失败,用perror来打印错误信息,若成功,则在后面使用这块空间,对前50个空间赋值为0-50,并打印出来
运行结果:
但是这还并没有完,因为我们向内存开辟空间用完之后就得还给操作系统,不然的话,这块空间自己不用了,但别人也用不了,还在浪费内存,造成了内存泄漏的问题,这里用free来释放内存
free原型
void free (void* ptr);
这样来用
free(ps); //释放内存 ps = NULL; //将指针置空
因为free(ps)释放内存之后ps这个指针里面仍然还有这块空间的地址,所以我们应该要将ps及时置空,不然后面如果用ps来访问的话,就是非法的
- 如果参数ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的
- 如果参数ptr 是NULL指针,则函数什么事都不做
calloc
函数原型:
void *calloc( size_t num, size_t size );
参数:
size_t num 这是指定要存放多少个元素
size_t size 指定所要存放元素的每个元素的大小
这个函数会将所开辟的空间自动初始化为0
返回值:void*类型,若开辟成功,返回所开辟空间的地址,开辟失败,返回空指针
头文件:
使用:
#include#include int main() { int* ps = (int*)calloc(10,sizeof(int)); if (ps == NULL) { perror("malloc:"); return 0; } for (int i = 0; i < 10; i++) { printf("%d ", *(ps + i)); } free(ps); ps = NULL; return 0; }
realloc
这个函数用来动态调整所开辟的内存大小,realloc函数的出现让动态内存管理更加灵活
函数原型:
void *realloc( void *memblock, size_t size );
参数:memblock,要调整的内存的地址
size,调整之后的大小
返回值:调整之后内存的起始地址void*类型
头文件:
使用:
#include#include int main() { int* ps = (int*)calloc(10,sizeof(int)); if (ps == NULL) { perror("malloc:"); return 0; } //调整大小 int* ptr = (int*)realloc(ps, 20 * sizeof(int)); if (ptr == NULL) { perror("realloc"); } else { ps = ptr; ptr = NULL; } for (int i = 10; i < 20; i++) { *(ps + i) = i; } for (int i = 0; i < 20; i++) { printf("%d ", *(ps + i)); } return 0; }



