目录
一、malloc函数的相关应用
1.函数原型
void *malloc( size_t size );
2.函数功能
需要引用的头文件就是<stdlib.h>.表示了向堆区申请size个字节的连续的空间,并且将该空间的起始地址传回来,如果需要指定类型,只需要强制类型转化即可。
int main()
{
int* arr = (int*)malloc(sizeof(int) * 4);//向堆内存申请了四个int类型的空间,即16个字节。
if (arr != NULL)
{
//放数
for (int i = 0; i < 4; i++)
{
*(arr + i) = i + i * 2;
}
//验证
for (int i = 0; i < 4; i++)
{
printf("%d ", *(arr + i));
}
}
return 0;
}
这里为什么会放一个if来判断是否为空指针呢?不急,来看一下这个函数的返回与实现细节:
3.函数的实现细节
*malloc返回一个指向已分配空间的void指针,如果可用内存不足,则返回NULL。若要返回指向非void类型的指针,请对返回值进行类型转换。返回值所指向的存储空间保证对任何类型的对象进行适当的对齐。如果size为0,malloc会在堆中分配一个长度为0的项,并返回一个指向该项的有效指针。总是检查malloc的返回值,即使请求的内存量很小。
这就是为什么2.中加if判断是否为空指针,防止对空指针进行解引用出错。
4.函数的使用规范
注意到malloc函数是在堆内存开辟空间的,需要程序员手动释放其内存或者等程序结束后系统自动回收。因此,这样就会造成内存泄漏的问题。因为在一个程序里面如果你动态开辟的空间使用完后如果不进行回收释放,那么该空间将会一直倍占用持续到程序结束,占用内存小一点无所谓,如果大的话那么就很有问题的了。
需要注意的是:在该动态开辟的空间被释放的同时,一开始接受的首地址并没有回收,但此时它已经无效,如果此时不将接受的指针变量付给NULL的话那么就成了野指针了,这是非常危险的!
二、realloc函数的相关应用
1.函数原型
void *realloc( void *memblock, size_t size );
2.函数功能
需要引用的头文件就是<stdlib.h>.memblock表示了要扩展的地址,这相当于是一个扩展内存的函数,size表示了要重新扩展多大的字节空间,同样的也是连续内存,一般是扩展malloc函数开辟的动态内存的。当memblock指向的地址空间为NULL的时候,就和malloc一样。
int* a = (int*)realloc(arr, sizeof(int) * 8);//将原先arr申请的四个int类型的堆内存扩展到八个,也就是32个字节
if (a != NULL)
{
arr = a;
}
else
{
perror("int::calloc");//存在问题就报错
}
printf("\n扩展后:\n");
for (int i = 4; i < 8; i++)
{
*(arr + i) = i + i * 2;
}
for (int i = 0; i < 8; i++)
{
printf("%d ", *(arr + i));
}
上述代码是继承一里面的malloc函数代码实现的,基本细节也与malloc函数一致,就相当于扩展即可。
三、calloc函数的相关应用
1.函数原型
void *calloc( size_t num, size_t size );
2.函数功能
需要引用的头文件就是<stdlib.h>.size表示了开辟动态空间的类型所占字节,比如sizeof(int)就是一个,而num就是这个类型所要开辟对应空间要的个数。
int* arr = (int*)calloc(4, sizeof(int));//向堆内存申请了四个int类型的空间,并且全部都初始化0。
if (arr != NULL)
{
//验证是否初始化为0
printf("未赋值:\n");
for (int i = 0; i < 4; i++)
{
printf("%d ", *(arr + i));
}
printf("\n");
for (int i = 0; i < 4; i++)
{
*(arr + i) = i + i * 2;
}
printf("赋值后:\n");
//验证
for (int i = 0; i < 4; i++)
{
printf("%d ", *(arr + i));
}
}
这里不同的会在没有给空间填值的时候会默认赋给0,其余细节也和malloc函数一致。
四、memset函数应用
1.函数原型
void *memset( void *dest, int c, size_t count );
2.函数功能
需要引用的头文件是<string.h>.这个函数里面有三个参数,第一个表示了你要处理的连续内存地址给我,第二个处理成什么整数,第三个表示了批量处理多少字节的数据。
int* arr = (int*)malloc(sizeof(int) * 4);//向堆内存申请了四个int类型的空间,即16个字节。
if (arr != NULL)
{
memset(arr, 0, sizeof(int) * 4);//每个字节赋给0
printf("每个字节赋给0\n");
for (int i = 0; i < 4; i++)
{
printf("%d ", *(arr + i));
}
printf("\n");
memset(arr, 1, sizeof(int) * 4);//每个字节赋给1
printf("每个字节赋给1\n");
for (int i = 0; i < 4; i++)
{
printf("%d ", *(arr + i));
}
}
带入main函数运行结果是:
第一个赋给0好理解,第二个相当于是每一个字节赋给1,所以这里是有 0001 0000 0001 0000 0001 0000 0001
该函数在进行批量处理的时候非常方便。