关于calloc函数,malloc函数的理解(概念+例题讲解)

引入

我们在牛客网或者 leetcode刷题时经常遇到让你写核心代码的做题模式,作为一个刚开始刷题不久的新人,我在没有学习calloc函数时,遇到了需要用到此函数的相关题目。 不知道大家有没有和我一样的情况,我从头开始写就能写出来,但是遇到这种只让你写一部分(核心代码)的模式就变得不太会写了。

calloc函数和malloc函数

calloc函数:calloc函数用于分配指定数量的连续内存块,并返回一个指向该内存区域的指针。特点如下:

①函数原型:void *calloc(size_t num, size_t size);
②参数num指定要分配的元素数量,size指定每个元素的大小。
③函数返回值为指向分配的内存块的指针,如果分配失败则返回NULL。
④ calloc函数分配的内存块会被初始化为0(即每个字节都为0)。

malloc函数:malloc函数用于分配指定大小的内存块,并返回一个指向该内存区域的指针。特点如下:
①函数原型:void *malloc(size_t size);
②参数size指定要分配的内存块的大小。
③函数返回值为指向分配的内存块的指针,如果分配失败则返回NULL。 ④malloc函数分配的内存块的内容是未定义的,需要手动初始化。

两者区别

`

①内存块初始化:calloc函数会将分配的内存块中的每个字节都初始化为0,而malloc函数不会对分配的内存块进行初始化。
②参数个数:calloc函数需要指定要分配的元素数量和每个元素的大小,而malloc函数只需要指定分配的内存块的大小。
③效率:如果只是简单地分配内存块而不需要进行初始化,malloc函数比calloc函数更高效。

在实际使用中,可以根据实际需要选择使用calloc函数或malloc函数。如果需要快速地分配一块内存,并且不需要初始化其内容,则可以使用malloc函数。如果需要分配一块内存,并且要求每个字节都初始化为0,则可以使用calloc函数。

我的问题

集合 s 包含从 1 到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个数字复制了成了集合里面的另外一个数字的值,导致集合
丢失了一个数字 并且 有一个数字重复 。 给定一个数组 nums 代表了集合 S 发生错误后的结果。
请你找出重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。

我做题时遇到了这样一道题,刚开始我想这从头开始写,用完整的函数把它写出来。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
int i = 0;
int n = 0;
scanf("%d", &n);
int nums[10000] = { 0 };
for (int i = 0; i < n; i++)
{
scanf("%d", &nums[i]);
}
 if (n <= 2)
printf("1 2");
for (int i = 0; i < n-2; i++)
{
if (nums[i] + 1 != nums[i + 1])
{
printf("%d ", nums[i + 1]);
printf("%d", nums[i + 1] + 1);
}
}
return 0;
}

这是我谢了包括主函数部分完成的代码,当我要提交时发现题目只需提交核心代码,并且给了你一些预制参数。

在这里插入图片描述
此时我无法将我写的完整代码套入。

问题解决

int *findErrorNums(int *nums, int numsSize, int *returnSize)
{
int arr[10002] = {0};
int *res = malloc(sizeof(int) * 2);
//动态分配一个包含2个元素的整型数组res。这里假设找到的重复元素最多有一个,所以只需要一个元素存储重复元素的值。

int *findErrorNums(int *nums, int numsSize, int *returnSize) 
{
    int arr[10002] = {0};
    int *res = malloc(sizeof(int) * 2);
//动态分配一个包含2个元素的整型数组res。这里假设找到的重复元素最多有一个,所以只需要一个元素存储重复元素的值。

    for (int i = 0; i < numsSize; ++i) 
    {
        arr[nums[i]]=arr[nums[i]]+1;
        if(arr[nums[i]]==2) 
        res[0] = nums[i];
    }

    for (int i = 0; i < numsSize; ++i) 
    {
        if(arr[i+1]==0) 
        res[1] = i+1;
    }
    *returnSize = 2;
    return res;
}

最后通过的代码如上。此代码很好的运用了malloc函数,我认为此例子也是我对malloc函数有了一些基础的认识。同时还了解到了calloc函数。

①首先,定义一个长度为10002的整型数组arr,用于存储数组nums中每个元素的出现次数。因为题目中给定的数组范围是1到10000,所以需要定义一个比数组长度大2的数组。

②然后,动态分配一个长度为2的整型数组res,用于存储找到的重复元素和缺失的元素。

③接着,通过遍历数组nums,使用arr数组记录每个元素的出现次数。如果某个元素的出现次数为2,说明它是重复的元素,将其赋值给res数组的第一个元素。

④接下来,再次遍历数组nums的长度。如果arr数组中某个下标对应的值为0,说明该下标对应的元素未出现过,即为缺失的元素,将该下标加1赋值给res数组的第二个元素。

⑤最后,将res数组的长度设置为2,并返回res数组。

其中用到了malloc函数
*"int res = malloc(sizeof(int) * 2);"
此行使用malloc函数动态分配了一个大小为2个整型元素的内存空间,并将该空间的起始地址赋值给整型指针res。

int *findErrorNums(int *nums, int numsSize,int *returnSize)

此行定义了一个函数findErrorNums,它接受一个整型指针nums、一个整型numsSize和一个整型指针returnSize作为参数,并返回一个整型指针。这是土木中的预制参数。
因为最后要返回一个指针类型的数组,所以我们使用malloc函数开辟一个数组空间。

除此之外还可以将malloc函数换成calloc函数,但需要注意calloc函数会将分配的内存块中的每个字节都初始化为0,而malloc函数不会对分配的内存块进行初始化。因此,如果在代码中使用了malloc函数分配内存后立即对该内存进行初始化操作,可以将malloc函数换成calloc函数,从而避免重复的初始化操作。

总结

该函数使用malloc函数来动态分配一个包含2个元素的整型数组res。这是因为函数需要返回两个数值,一个是重复的元素值,另一个是缺失的元素值。为了能够在函数结束后仍然可以使用这两个数值,需要将它们存储在堆内存中,而不是函数内的栈内存中。

使用malloc函数动态分配内存,可以确保在函数结束后仍然可以访问到这两个数值。通过将返回的指针保存在res中,可以在函数外部访问和使用这两个数值。这样可以为调用该函数的代码提供更灵活的使用方式和更大的扩展性。

当然,这只是这个函数最简单的用法,除此之外我还了解到:
其他题目在使用完这两个数值后,需要手动使用free函数释放通过malloc动态分配的内存空间,以避免内存泄漏的问题。

如有错误也请大家批评指正!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chris·Bosh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值