动态内存:
malloc and free
#include<stdio.h>
#include<malloc.h>
#include<errno.h>
int main() {
//像内存申请10个整形的空间
int* p = (int*)malloc(10 * sizeof(10*int));//malloc函数前需要强制类型转化,因为其为void类型
if (p == NULL) //malloc函数的返回值一定要检查,否则容易犯错
{
//打印错误原因的一个方式
printf("%s\n", strerror(errno));
}
else {//正常使用
int i = 0;
for (i; i < 10; i++) {
*(p + i) = i;
printf("%d", *(p + i));
}
}
//当动态申请的空间不再使用,应该要释放还给系统
free(p);
p = NULL;
return 0;
}
黄色荧光笔部分为动态内存的使用格式
calloc and free
#include<stdio.h>
#include<malloc.h>
#include<errno.h>
int main() {
//像内存申请10个整形的空间
int* p = (int*)calloc(10 , sizeof(int));//注意calloc(元素个数,单个元素长度),malloc(元素个数*单个元素长度)
if (p == NULL) //malloc函数的返回值一定要检查,否则容易犯错
{
//打印错误原因的一个方式
printf("%s\n", strerror(errno));
}
else {//正常使用
int i = 0;
for (i; i < 10; i++) {
*(p + i) = i;
printf("%d", *(p + i));
}
}
//当动态申请的空间不再使用,应该要释放还给系统
free(p);
p = NULL;
return 0;
}
注意:malloc不初始化,要手动初始化,效率更高,但不初始化,calloc已经自动初始化每个元素为零,效率低但初始化
realloc:调整动态开辟内存的大小
- 如果原有空间足够追加,则在原有空间基础上追加
- 若原有空间不足以追加,则realloc则重新找一块内存区域,开辟一块满足需求的内存空间,并把原数据拷贝回来,释放旧的内存空间。
- 得用一个新的变量来接受realloc函数的返回值
使用格式:
(类型)*变量名 = (强制类型转化)realloc(需要改变的动态内存地址,改变后的字节数)
eg:将20个字节大小的内存改为四十个字节大小的内存
int* p = (int*)malloc(20);
int* ptr = (int*)realloc(p,40);
三个忌讳:
1.对NULL指针的解引用
即需要我们去判断是否成功开辟的动态内存,判断返回值是否为NULL。
- 对动态内存的越界访问
即使用空间必须<=开辟空间,例:开辟五个字节,初始化十个数
- free非动态指针,free只能free堆区的,不能free栈区的,静态内存在栈区
- 部分释放动态内存的空间
解引用应用*(p+ i)
- 对同一块内存多次释放
多次free(p)
6.动态开辟内存忘记释放(内存泄漏)
杂记:char* str = “abcd”;
printf(str);是正确的