1. malloc()函数和free()函数

首先,我们应该知道。所有的程序都必须留出足够的内存空间来存储所使用的数据,所以我们常常会预先给程序开辟好内存空间,然后进行操作,但事实上另一种选择,能够让内存分配自己主动进行下去。

对于传统数组,会遇到这种问题:

int arr[5] ;

对这个数组我们在定义的时候必须给提前开辟好空间。而且在程序运行的过程中,这个开辟的内存空间是一直存在的。除非等到这个函数运行完成,才会将空间释放。

另一个问题就是这个数组在程序中无法被改动。

这些问题给我们造成了一些使用上的不方便,所以,C中提供了malloc()函数。

关于malloc()函数。这个函数它接受一个參数:就是所需的内存的字节数。然后malloc()找到可用内存中那一个大小适合的块。在这个过程中,malloc()能够来返回那块内存第一个字节的地址。所以。也就意味了我们能够使用指针来操作。malloc()能够用来返回数组指针、结构指针等等。所以我们须要把返回值的类型指派为适当的类型。当malloc()找不到所需的空间时。它将返回空指针。

例:

double *p;
p=(double*)malloc(30*sizeof(double));

在这个程序中,首先开辟了30个double类型的空间,然后把p指向这个空间的位置。在这里的指针是指向第一个double值。

并非我们所有开辟的30个double的空间。

这就和数组一样,指向数组的指针式指向数组首元素的地址,并非整个数组的元素。所以,在这里我们的操作也和数组是一样的,

p[0]就是第一个元素。p[2]就是第二个元素。

至此。我们就能够掌握到一种声明动态数组的方法。

int arr[n];
p=(int *)malloc(n*sizeof(int));
//我们在这里使用的时候要元素个数乘类型字节长度。这样就达到了动态开辟内存空间。

当我们使用malloc()开辟完内存空间以后,我们所要考虑的就是释放内存空间,在这里,C给我们提供了free()函数。

free()的參数就是malloc()函数所返回的地址,释放先前malloc()函数所开辟的空间。

例:

对于上面我们所开辟的空间进行释放,那么我们就能够这样

free(p);

程序还调用了exit()函数,这个函数是在内存分配失败时结束程序。

程序样例:


#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<malloc.h>//malloc()函数被包括在malloc.h里面
#include<stdlib.h>
int main(void)
{
char*a = NULL;//声明一个指向a的char*类型的指针
a = (char*)malloc(100 * sizeof(char));//使用malloc分配内存的首地址。然后赋值给a
if (!a)//假设malloc失败。能够得到一些log
{
perror("malloc");
return-1;
}
sprintf(a, "%s", "HelloWorld\n");//"HelloWorld\n"写入a指向的地址
printf("%s\n", a);//输出用户输入的数据
free(a);//释放掉使用的内存地址
system("pause");
return 0;//例2有无内存泄露?
}

这个程序主要用来检測malloc返回值条件有误。

在这里我们须要注意,在C中,类型指派(char *)是可选的,可是在C++中这个是必须有的,所以使用类型指派将使把C程序移植到C++更easy。

使用动态数组,主要是为了获得程序的灵活性。我们嗯能够须要多少个元素就让数组开辟多少个。。

不须要浪费空间

2.free()的重要性

在我们使用malloc()函数的时候。分配的内存是会添加的,当我们使用free()函数时,能够释放内存。
比如:
...

int main()
{
double glad[2000];
int i;
...
for(i=0;i<1000;i++)
gobble(glad,2000);
...
}
void gobble(double arr[],int n)
{
double *temp=(double *)malloc(n*sizeof(double));
...
}

在这个程序其中我们使用了malloc()函数,可是我们没有使用free()函数,在这个程序中,我们首先进入gobble()函数,穿件了指针temp,而且使用了malloc()函数。可是除了gobble()函数之后,指针作为一个变量消失了,可是所开辟的内存是依旧存在的,我们依旧开辟了16000个字节的内存。

可是我们却无法去訪问这些内存。由于他们的地址不见了。由于没有调用free()函数,这段内存也不能再此使用了。

这样依次循环。总共运行for循环1000次。终于导致了程序总共16000000个字节的内存无法使用,这样。内存肯定已经溢出了。

这样就会出现我们所说的程序泄漏问题,而free()函数,正好攻克了这种的问题。

3.calloc()函数和realloc()函数

接下来。我们在认识两个关于内存分配的函数。calloc()函数和realloc()函数。

calloc()函数与malloc()函数有同样之处。也有类似之处。

例:

short *p;
newmem=(short *)calloc(1000,sizeof(short));

通过这个样例,我们能够知道calloc()函数有两个參数。而且这两个函数都是size_t类型(unsigned int类型)的数。

第一个參数在这里所说的是所须要开辟的内存单元数量。第二个參数是每一个单元的字节的大小。

void *calloc(size_t ,size_t);

calloc()函数另一个特性。它将块中的所有位都置为0。这也是calloc()函数和malloc()函数的差别,calloc()函数和malloc()函数的另外一个差别是他们请求内存数量的方式不一样。当然。free()函数也能够来释放calloc()函数分配的内存。

realloc()函数用来改动一个原先已经分配的内存的大小。使用这个函数,你能够让一块内存增大还是缩小。当扩大时。这块内存原先的内容会依旧保留,新添加的加入到原先的后面。缩小时,该内存的尾部部分内存去掉,剩余保留。

注意:对于realloc()函数。假设原先的内存无法改动。这时候realloc()函数再会分配一块内存。而且把原先那块内存的内容拷贝到上面去。

所以。使用了realloc函数以后,你这时候在使用的就该是realloc函数返回的新指针了。当realloc函数的第一个參数是NULL时,这时候我们能够把它当作是malloc()函数。

写博客已经半个月了,感觉问题还是非常多。希望大家多多指点。

最新文章

  1. 【原创】Kakfa log包源代码分析(一)
  2. 内外分离接口依赖及UIScrollView知识点
  3. 【代码笔记】iOS-淡出淡入效果
  4. Android源代码之Gallery专题研究(1)
  5. linux内存管理系列 +CFS 图解
  6. WordPress wp-includes/functions.php脚本远程任意代码执行漏洞
  7. Javascript中的位运算符和技巧
  8. Chrome 插件集锦
  9. github not authorized eclipse 关于 代码不能提交到GitHub
  10. 深入理解ES6之—符号与符号属性
  11. [bzoj4552][Tjoi2016&amp;Heoi2016]排序-二分+线段树
  12. SpringMVC源码分析--文件上传
  13. How to view the DNS address assigned by DHCP
  14. JavaScript主流框架3月趋势总结
  15. java学习之—递归实现二分查找法
  16. asp.net ajax控件选项卡控件的选项卡的动态显示与隐藏问题
  17. 1.1初识python
  18. 转:SQL Server - 使用 Merge 语句实现表数据之间的对比同步
  19. Linux C++调试利器-gdb
  20. Linux进程管理工具 Supervisord 的安装 及 入门教程

热门文章

  1. Expert C Programming 阅读笔记(CH2)
  2. Knockout介绍
  3. Java 中如何计算两个字符串时间之间的时间差?(单位为分钟)
  4. CodeForces 785C Anton and Fairy Tale
  5. Hibernate 组合主键映射
  6. ARGB 8888 内存大小
  7. codevs 1102 采药 2005年NOIP全国联赛普及组
  8. win7环境下一次浅谈栈溢出
  9. 工作中用到的git命令
  10. hdu 1711