malloc函数
malloc-->void* malloc (size_t size);
malloc函数用于开辟堆的连续内存空间,参数是需要开辟多大的空间,单位是字节,返回值为无类型的指针
malloc的详解
头文件<stdlib.h>
1.参数传入
size_t size:开辟的空间的大小,单位是字节
特殊情况:传入参数为0时间,函数返回值取决于特定的库实现(即C语言未定义标准行为,有可能返回空指针)
2.返回值
返回值是指针
开辟成功:指向开辟空间开始的内存块
开辟失败:返回空指针
为了确保开辟内存的成功,使用前一定要对指针进行验证
由于返回类型是无类型的指针,使用时要强制类型转换
3.空间内容
新开辟的空间是未被初始化的,是不确定的值
实例
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(sizeof(int)*10); //开辟了40个字节的空间
if (p == NULL)
{
printf("开辟空间失败");
return 1; //C语言习惯,程序运行成功返回0,失败返回1
}
//为空间添加值
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;
//*(p + i) = i 等价于 p[i] = i
}
//此内存使用完毕后,需要及时释放,防止内存泄漏
free(p);
return 0;
}
运行结果
calooc函数
calloc-->void* calloc (size_t num, size_t size);
calloc函数用于开辟堆的连续内存空间,参数有两个,第一个是需要开辟多少个元素,第二个是每个元素的大小,单位是字节,返回值为无类型的指针
calloc详解
头文件<stdlib.h>
1.参数传入
size_t num:开辟元素的个数
size_t size:开辟元素的大小,单位是字节
特殊情况:传入参数为0时间,函数返回值取决于特定的库实现(即C语言未定义标准行为,有可能返回空指针)
2.返回值(与malloc的一样)
返回值是指针
开辟成功:指向开辟空间开始的内存块
开辟失败:返回空指针
为了确保开辟内存的成功,使用前一定要对指针进行验证
由于返回类型是无类型的指针,使用时要强制类型转换
3.空间内容(区别于malloc的地方)
开辟空间的内容会被初始化为0
实例
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i = 0;
//malloc
int* p = (int*)malloc(10 * sizeof(int));
if (p ==NULL)
{
printf("失败");
return 1;
}
for (i = 0; i < 10; i++)
{
printf("%d\n", p[i]);
}
free(p);
//calloc
int* pc = (int*)calloc(10,sizeof(int));
if (pc == NULL)
{
printf("失败");
return 1;
}
for (i = 0; i < 10; i++)
{
printf("%d\n", pc[i]);
}
free(pc);
return 0;
}
运行结果
malloc与calloc的区别
1.malloc对开辟的空间不做初始化,calloc对开辟的空间全部初始化为0
2.malloc参数传入的是需要开辟空间的字节总数,而calloc参数为需要开辟元素的个数与每个元素的大小
realloc函数
realloc-->void* realloc (void* ptr, size_t size);
ralloc函数用于新增加由malloc\calloc函数创建的内存空间,第一个参数是先前创建地址的指针,第二个参数是需要的空间大小(总空间大小=先前空间大小+需要增加的空间大小)
realloc详解
头文件<stdlib.h>
1.参数传入
void* ptr:先前由malloc\calloc等函数分配的地址
特殊情况:传入的是NULL空指针,它的作用会和malloc的作用一样
size_t size:传入的是总需要开辟的空间大小,例如你用malloc开辟了40个字节的大小,你需要新增40个字节,所以总空间为80个字节,则传入80字节
特殊情况:size为0时,传入参数为0时间,函数返回值取决于特定的库实现(即C语言未定义标准行为,有可能返回空指针)
2.返回值
返回值是指针
开辟成功:指向重新分配空间的地址,重新分配的地址有可能与原先的地址相同,也有可能不同
相同情况(情况一):先前空间地址后面有一块可以连续存放新增内存大小的空间
不相同情况(情况二):先前空间地址后面的内存不足以存放新增内存的大小,需要在堆区重新找一块新的空间
开辟失败:返回空指针
为了确保开辟内存的成功,使用前一定要对指针进行验证
由于返回类型是无类型的指针,使用时要强制类型转换
3.空间内容
若内存块被移到新的位置(情况2),里面的内容也会会拷贝到新的空间,且新开辟的空间的值未初始化
实例
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* p = (int*)malloc(40);
//增加数据
int i = 0;
for (i = 0; i < 10; i++)
{
p[i] = i;
}
//内存扩容
int* ptr = (int*)realloc(p, 80);
//内存新增成功时,才敢把新的指针赋值给p指针
//否则p = (int*)realloc(p, 80);当新增失败时,p也会变成NULL,则原先的数据也会找不到
if (ptr != NULL)
{
p = ptr;
}
for (i = 0; i < 15; i++)
{
printf("%d\n", p[i]);
}
free(p);
return 0;
}
运行结果
free函数(所有动态申请内存函数使用后必须要的使用的)
free-->void free (void* ptr);
释放申请的内存空间,参数为申请内存空间返回的指针,malloc等函数只会申请空间,当不用free释放时,堆中的可用空间会越来越少,最终影响性能等
free详解
头文件<stdlib.h>
1.参数传入
参数必须是由malloc\calloc\realloc函数申请的空间的指针
指针为空指针时,函数什么都不会做
指针不是malloc\calloc\realloc函数申请的空间的指针时,这个为C语言未定义行为,执行什么取决于编译器
2.返回值
没有返回值
注意:free函数不会改变指针指向的值,释放后仍指向原来的值,只是此时的空间没有内容了