好了承接上文,我们来讲
calloc函数
calloc 是 C 语言中另一个用于动态内存分配的函数。与 malloc 不同,calloc 不仅分配内存,还会将分配的内存初始化为零。这在某些情况下非常有用,特别是当你需要一个初始值为零的数组或结构时。
void* calloc(size_t num, size_t size);
size_t num:要分配的元素数量。
size_t size:每个元素的大小(以字节为单位)。
返回值:指向分配内存的指针,如果分配失败还是返回 NULL。
函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
举个例子
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
int n = 5;
// 分配并初始化内存
ptr = (int*)calloc(n, sizeof(int));
if (ptr == NULL) {
printf("内存分配失败\n");
return 1;
}
// 打印结果,验证内存是否被初始化为零
for (int i = 0; i < n; i++) {
printf("%d ", ptr[i]);
}
printf("\n");
// 使用分配的内存
for (int i = 0; i < n; i++) {
ptr[i] = i * 2;
}
// 再次打印结果
for (int i = 0; i < n; i++) {
printf("%d ", ptr[i]);
}
printf("\n");
// 释放内存
free(ptr);
ptr = NULL; // 将指针设置为 NULL
return 0;
}
这里输出结果是
0 0 0 0 0
0 2 4 6 8
正因为calloc 会将分配的内存块中的所有字节初始化为零。这对于需要初始化为零的数据结构特别有用。而且calloc 分配的内存通常是按平台的字节对齐要求进行对齐的。
不信我们来看,这里我们在vs里面看一下内存的具体地址
这样就很直观的看出来,是按照字节的对齐要求来初始化的了。
realloc函数
realloc 是 C 语言中用于重新分配内存的函数。它允许你调整之前通过 malloc、calloc 或 realloc 分配的内存块的大小。
如果需要更多的内存,realloc 会尝试扩展现有的内存块;
如果需要更少的内存,realloc 会尝试缩小现有的内存块。
如果无法在原位置调整内存大小,realloc 会分配一个新的内存块,并将原有数据复制到新位置,然后释放原有的内存块。
void* realloc(void* ptr, size_t new_size);
ptr:要调整的内存地址。如果 ptr 为 NULL,则 realloc 的行为类似于 malloc(new_size)。
new_size:调整之后新大小。
返回值:为调整之后的内存起始位置。如果重新分配失败,返回 NULL,并且原来的内存块保持不变。
realloc在调整内存空间的是存在两种情况:
情况1:原有空间之后有足够大的空间
情况2:原有空间之后没有足够大的空间 这里画图给大家讲解一下
情况1当是情况1 的时候,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。
情况2当是情况2的时候,原有空间之后没有足够多的空间时,扩展的方法是:在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址。
由于上述的两种情况,realloc函数的使用就要注意一些。举个例子
#include <stdio.h>
int main()
{
int *ptr = malloc(100);
if(ptr != NULL)
{
//业务处理
}
else
{
exit(EXIT_FAILURE);
}
//扩展容量
//代码1
ptr = realloc(ptr, 1000);//这样可以吗?(如果申请失败会如何?)
如果realloc申请内存失败,它会返回NULL。因此,你需要检查realloc的返回值,以确保操作成功。如果失败,通常的做法是保留原有的内存块并进行错误处理。
void* temp = realloc(ptr, 1000);
if (temp == NULL) {
// 内存分配失败,处理错误
fprintf(stderr, "Memory reallocation failed\n");
// 可以选择释放原有内存并退出程序
free(ptr);
exit(EXIT_FAILURE);
} else {
// 更新指针
ptr = temp;
}
像这样,就可以正确处理了,这里再给大家放一段正确安全申请空间的代码供大家自己探索。有必要的注释在里面。
好,因为我的复制粘贴逐字成行的缘故,暂时写到这里,下一篇文章我会给大家讲一下一些动态内存管理的笔试题。
感谢阅读!