当前位置:   article > 正文

Malloc,calloc,realloc函数的学习_ret[i] = malloc(sizeof(int) * (i + 1));

ret[i] = malloc(sizeof(int) * (i + 1));

一:首先我们需要了解malloc的作用是什么,malloc的作用就是动态申请一块内存;

在此之前我们需要引入#include<stdlib.h>头文件

  1. int main()
  2. {
  3. int* arr;
  4. int i;
  5. arr=(int*)malloc(sizeof(int)*100); //malloc 申请一块内存
  6. for(i=0;i<100;i++)
  7. {
  8. arr[i]=i;
  9. }
  10. for(i=0;i<100;i++)
  11. {
  12. printf("%d ",arr[i]);
  13. }
  14. free(arr);
  15. arr=NULL
  16. return 0;
  17. }

int *ret 其实就是一个指针,指向所申请的空间,所以在malloc函数前我们需要加上()这样的强制转换符

malloc内部我们需要用sizeof计算数据所需要的字节数,比如我想申请100个int型的空间,那么int 所占的字节数就是4或8,我们需要100个那我们就需要乘上100.

因为malloc是在堆上进行使用,使用我们需要手动释放内存;

Malloc:其实就是可以动态申请内存的函数,能很好地弥补静态分配的缺点。

静态分配的缺点:

它申请的内存不能手动释放,它所申请的内存实际上是在栈上申请的,类似如c语言中函数的调用,都是通过在栈上调用内存。栈上调用的函数在执行完成后就会被释放,而在堆上调用的函数则需要手动释放。malloc函数则是在堆上调用的

那么相比于直接使用arr【100】={0}这种获取内存的方式有什么区别呢?

我们从调用函数来看看:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. int* GetArray()
  4. {
  5. int ret[100]={0};
  6. return ret;
  7. }
  8. int main()
  9. {
  10. int i;
  11. int* arr=GetArray();
  12. for(i=0;i<100;i++)
  13. {
  14. printf("%d ",arr[i]);
  15. }
  16. printf("\n");
  17. return 0;
  18. }

可以看出打印数组的时候产生了很多的垃圾数据,而且编译器报了警告。

如果我们使用malloc抓住这一段空间,那么会怎么样呢?

  1. int* GetArray()
  2. {
  3. int i;
  4. //int ret[100]={0};
  5. int*ret=(int*)malloc(sizeof(int)*100);
  6. for(i=0;i<100;i++)
  7. {
  8. ret[i]=0;
  9. }
  10. return ret;
  11. }
  12. int main()
  13. {
  14. int i;
  15. int* arr=GetArray();
  16. for(i=0;i<100;i++)
  17. {
  18. printf("%d ",arr[i]);
  19. }
  20. printf("\n");
  21. printf("%p",arr);
  22. free(arr);
  23. arr=NULL;

结果可以看出数据成功变成了我们所设的数据,这就体现出malloc对于分配内存空间的作用。

关于释放内存

当我们利用指针遍历数组并打印时,我们可以利用malloc获取内存,然后通过指针将其内存首地址存放在一个指针变量中,然后最后我们释放这个指针变量就可以完成内存释放操作。

二:calloc函数:

calloc函数的作用是为我们使用malloc函数申请的那块空间进行初始化,具体操作如下:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. int main()
  4. {
  5. int* arr;
  6. int i;
  7. arr=(int*)malloc(sizeof(int)*100); //malloc 申请一块内存
  8. /*arr=(int*)calloc(100,sizeof(int)); //calloc 初始化数据
  9. for(i=0;i<100;i++)
  10. {
  11. arr[i]=i;
  12. }*/
  13. for(i=0;i<100;i++)
  14. {
  15. printf("%d ",arr[i]);
  16. }
  17. return 0
  18. }

当我们不进行初始化操作时,这块空间的值是杂乱的;

当我们进行初始化操作后

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. int main()
  4. {
  5. int* arr;
  6. int i;
  7. arr=(int*)malloc(sizeof(int)*100); //malloc 申请一块内存
  8. arr=(int*)calloc(100,sizeof(int)); //calloc 初始化数据
  9. for(i=0;i<100;i++)
  10. {
  11. arr[i]=i;
  12. }
  13. for(i=0;i<100;i++)
  14. {
  15. printf("%d ",arr[i]);
  16. }
  17. return 0
  18. }

由此可见,所有值都被初始化为零;

三:realloc 的使用

这里我们可以分为两个情况

第一个情况:小扩容

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. int* GetArray()
  4. {
  5. int i;
  6. int*ret=(int*)malloc(sizeof(int)*100);
  7. ret=(int*)calloc(100,sizeof(int)); //calloc 初始化数据
  8. return ret;
  9. }
  10. int main()
  11. {
  12. int i;
  13. int* arr=GetArray();
  14. int* arr1=(int*)realloc(arr,110*sizeof(int));//内存扩容
  15. for(i=0;i<110;i++)
  16. {
  17. arr1[i]=i;
  18. }
  19. for(i=0;i<110;i++)
  20. {
  21. printf("%d ",arr1[i]);
  22. }
  23. printf("\n");
  24. printf("%p\n",arr);
  25. printf("%p",arr1);
  26. free(arr);
  27. arr=NULL;
  28. return 0;
  29. }

通过结果我们可以看出,扩容前的arr和扩容后的arr1的首元素地址都相同,这就是我们的第一种情况

黑色方块代表这块内存已经被使用,如果扩容内存比较小的话,就可以正常进行扩容且首地址是相同的;

如果扩容内存过大那么会造成什么呢?

我们的内存分配情况就会像第三种情况一样,第二种显然是不行的,因为那块空间已经被人利用了,第三种则为在内存充足的地方再划分一块进行分配

这就是大扩容:

代码显示如下:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. int* GetArray()
  4. {
  5. int i;
  6. int*ret=(int*)malloc(sizeof(int)*100);
  7. ret=(int*)calloc(100,sizeof(int)); //calloc 初始化数据
  8. return ret;
  9. }
  10. int main()
  11. {
  12. int i;
  13. int* arr=GetArray();
  14. int* arr1=(int*)realloc(arr,10000*sizeof(int));//内存扩容
  15. for(i=0;i<10000;i++)
  16. {
  17. arr1[i]=i;
  18. }
  19. for(i=0;i<10000;i++)
  20. {
  21. printf("%d ",arr1[i]);
  22. }
  23. printf("\n");
  24. printf("%p\n",arr);
  25. printf("%p",arr1);
  26. free(arr);
  27. arr=NULL;
  28. return 0;
  29. }

可以看出扩容后arr和arr1的首地址不相同了,这也可以验证第三种是正确的;

首地址的不同很可能导致程序会出现错误

扩容的优化:

  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. int* GetArray()
  4. {
  5. int i;
  6. int*ret=(int*)malloc(sizeof(int)*100);
  7. ret=(int*)calloc(100,sizeof(int)); //calloc 初始化数据
  8. return ret;
  9. }
  10. int main()
  11. {
  12. int i;
  13. int* arr=GetArray();
  14. arr=(int*)realloc(arr,10000*sizeof(int));//内存扩容
  15. for(i=0;i<10000;i++)
  16. {
  17. arr[i]=i;
  18. }
  19. for(i=0;i<10000;i++)
  20. {
  21. printf("%d ",arr[i]);
  22. }
  23. printf("\n");
  24. printf("%p\n",arr);
  25. printf("%p",arr);
  26. free(arr);
  27. arr=NULL;

我们将arr1改成arr就可以很好的避免首地址不相同的情况了

也可以保证扩容的正确使用;

以上如有错误,感谢指正!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/600567
推荐阅读
相关标签
  

闽ICP备14008679号