1.malloc
当我们想开辟一块动态内存空间的时候,就需要使用动态内存函数了,比如
char* p;
当我们想要使用地址p下的内存时,就需要用到malloc函数
void* malloc(size_t size);
注意,malloc函数的返回类型是(void*),形参是要开辟空间的字节数。所以要使用malloc这个函数,必须将返回值强制类型转换为想要的类型,比如
1. char* p1=(char*)malloc(10);//在p1这个地址下开辟10个字节空间,可以存放10个char型数据 2. int* p2=(int*)malloc(20);//在p2这个地址下开辟20个字节空间,可以存放5个int型数据
注意,malloc函数开辟内存空间有时会开辟失败,这时会返回空指针(NULL),所以,要较好的使用malloc函数,还要检查一下是否成功开辟内存,代码如下
1. int* p=(int*)malloc(20);//开辟内存空间 2. if(p==NULL) 3. { 4. printf("%s",strerror(errno));//打印开辟失败的原因 5. }
需要知道的是,malloc函数开辟的内存空间不会自动初始化,里面放的是随机值
1. int* p = (int*)malloc(20);//开辟内存空间 2. if (p == NULL) 3. { 4. printf("%s", strerror(errno));//打印开辟失败的原因 5. } 6. else 7. for (int i = 0; i <5 ; i++)//访问新开辟的内存 8. { 9. printf("%d", (int)*(p + i)); 10. }
结果如下
malloc函数算是讲完了,但有一个非常重要的点并没有提到。我们知道创建一个数组相当于向内存空间申请了连续的一块空间,数组申请的内存空间是在栈上的,数组离开作用域会自动销毁,释放内存。
但是这里用malloc函数申请的内存空间是在堆上的,出作用域不会销毁,必须手动释放内存,否则会造成内存泄漏!(即使退出程序OS会自动回收内存,还是要有手动释放的好习惯)
手动释放内存需要使用free函数,free函数会把开辟的内存释放,内存的首地址就会变成野指针,所以还要将首地址置为空。代码如下
1. int* p = (int*)malloc(20);//开辟内存空间 2. if (p == NULL) 3. { 4. printf("%s", strerror(errno));//打印开辟失败的原因 5. } 6. //使用 7. 8. //手动释放空间 9. free(p); 10. p = NULL;
2.calloc
不同于malloc的是,calloc函数会自动将新开辟的内存空间初始化为全0
void* calloc(size_t num,size_t size);
size_t num:开辟的个数
size_t size:开辟的类型大小
例如,开辟5个整型空间
1. #include<stdlib.h> 2. #include<errno.h> 3. #include<string.h> 4. #include<stdio.h> 5. int main() 6. { 7. int* p = (int*)calloc(5,4);//开辟内存空间 8. if (p == NULL) 9. { 10. printf("%s", strerror(errno));//打印开辟失败的原因 11. } 12. else 13. //使用 14. 15. free(p); 16. p = NULL; 17. return 0; 18. } 19.
3.realloc
realloc函数用于原开辟的空间不足的情况下开辟更大的空间
void* realloc(void* ptr,size_t size);
void* ptr:原空间首地址
size_t size:新空间字节大小
realloc函数开辟新的空间会遇到两种情况
- 原空间后面空间充足,在原空间后面继续开辟新的空间,返回的地址和原地址相同。
- 原空间后面空间不足:
- realloc会找到更大的空间
- 将原来的数据拷贝到新的空间
- 释放旧的空间
- 返回新空间的地址(不同于原地址)
1. #include<stdlib.h> 2. #include<errno.h> 3. #include<string.h> 4. #include<stdio.h> 5. int main() 6. { 7. int* p = (int*)calloc(5,4);//开辟内存空间 8. if (p == NULL) 9. { 10. printf("%s", strerror(errno));//打印开辟失败的原因 11. } 12. else 13. //使用 14. for (int i = 0; i < 5; i++) 15. { 16. printf("%d ", *(p + i)); 17. } 18. p=realloc(p, 40);//扩大内存空间,将20字节增到40字节 19. for (int i = 0; i < 10; i++) 20. { 21. printf("%d ", *(p + i)); 22. } 23. free(p); 24. p = NULL; 25. return 0; 26. }