一、malloc和free
1.如果开辟成功,则返回一个指向开辟好空间的指针。2.如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。3.返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。free函数用来释放动态开辟的内存。1.如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。2.如果参数 ptr 是NULL指针,则函数什么事都不做。
1.1 malloc的使用
int main()
{
//1.动态内存开辟
int* p = (int*)malloc(10*sizeof(int));
//2.使用这些空间
if (p == NULL)
{
perror("main");
return 0;
}
//使用
int i = 0;
for (i=0; i<10; i++)
{
*(p + i) = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ",p[i]);
}
//回收空间
free(p);
p = NULL;
return 0;
}
//
int main()
{
int a = 10;
int* p = &a;
free(p); //err,free只能释放堆上开辟的内存空间起始地址
return 0;
}
1.2 内存泄露
/动态内存开辟常见的错误
//1.对NULL指着的解引用操作
//2.对动态开辟空间的越界访问
//3.使用free释放非动态开辟的空间
//4.使用free释放动态内存中的一部分
//5.对同一块动态开辟的空间,多次释放
//6.动态开辟的空间忘记释放- 内存泄漏-比较严重的
动态开辟的内存,只有2种释放方式1. 主动释放free2.程序结束//p是一个局部变量,test()函数执行完后p会自动销毁,但malloc开辟的内存空间不会自动销毁,所以开辟的新空间无法找到;而main函数中也找不到此空间,因此存在内存泄露
void test()
{
int* p = (int*)malloc(100);
if (p == NULL)
return;
//使用
}
int main()
{
test();
return 0;
}
二、calloc
//1. int* p = calloc(10,sizeof(int)); 开辟10个int型空间
//2.malloc不会初始化,一开始打印是随机值;calloc是默认初始化全为0
int main()
{
int* p = calloc(10,sizeof(int));
for (int i = 0; i < 10; i++)
{
printf("%d\n",*(p+i));
}
free(p);
p = NULL;
return 0;
}
三、realloc
realloc调整空间,有2种情况
//1. 再开10个int,p指向的空间后面有内存
//2. p指向的空间后面内存被其他程序占用,无法开辟10个int,realloc另外寻找一个20个int空间,将原
//空间的内容复制到新空间,在返回新空间的起始地址
注意:
//realloc有可能会找不到合适的空间,这时会返回NULL
int main()
{
int* p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
{
perror("main");
return 0;
}
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = 5;
}
//这里需要p指向更大的空间,需要20个int的空间
int* ptr = realloc(p, 20*sizeof(int));
if (ptr != NULL)
{
p = ptr;
}
free(p);
p = NULL;
return 0;
}
情况一:
情况二:
realloc实现malloc:
int main()
{
int* p1 = (int*)realloc(NULL,10*sizeof(int));
int* p2 = (int*)malloc(10*sizeof(int));
return 0;
}