malloc/free函数



malloc()函数用来在堆中申请内存空间,free()函数释放原先申请的内存空间。Malloc()函数是在内存的动态存储区中分配一个长度为size字节的连续空间。其参数是一个无符号整型数,返回一个指向所分配的连续存储域的起始地址的指针。当函数未能成功分配存储空间时(如内存不足)则返回一个NULL指针。


由于内存区域总是有限的,不能无限制地分配下去,而且程序应尽量节省资源,所以当分配的内存区域不用时,则要释放它,以便其他的变量或程序使用。


这两个函数的库头文件为:
#include<stdlib.h>
函数定义如下:


void *malloc(size_t size)   //返回类型为空指针类型
void free(void *ptr)
例如:


int *p1,*p2;
p1=(int *)malloc(10*sizeof(int));
p2=p1;
……
free(p2) ;      /*或者free(p1)*/ 
p1=NULL;       /*或者p2=NULL */
malloc()函数返回值赋给p1,又把p1的值赋给p2,所以此时p1,p2都可作为free函数的参数。使用free()函数时,需要特别注意下面几点:


(1)调用free()释放指针所指向的内存后,不能再去访问被释放的内存空间。内存被释放后,很有可能该指针仍然指向该内存单元,但这块内存已经不再属于原来的应用程序,此时的指针为悬挂指针(可以赋值为NULL),也称野指针,该区域的数据可能没有变,我们成为脏数据。


(2)不能两次释放相同的指针。因为释放内存空间后,该空间就交给了内存分配子程序,再次释放内存空间会导致错误。也不能用free来释放非malloc()、calloc()和realloc()函数创建的指针空间,在编程时,也不要将指针进行自加操作,使其指向动态分配的内存空间中间的某个位置,然后直接释放,这样也有可能引起错误。


(3)在进行C语言程序开发中,malloc/free是配套使用的,即不需要的内存空间都需要释放回收。


下面是使用这两个函数的一个例子。


[root@localhost yangzongde]# cat malloc_example.c 
#include<stdio.h>    //printf()    //(1)头文件信息
#include<stdlib.h>   //malloc()    //(2)
int main(void)   //(3)
{
int count;
int* array; 
if((array=(int *)malloc(10*sizeof(int)))==NULL)  //(重点)(4)分配空间    10*4(int)个连续的空间
{
printf("malloc memory unsuccessful");
exit(1);
}
for (count=0;count<10;count++)      //(5) 赋值
{
*array=count;
array++; //这就是为啥要为指针添加类型了
}
for(count=9;count>=0;count--)                  //(6)赋值
{
array--;
printf("%4d",*array);
}
printf("\n");
free(array);        //(7)释放空间
array=NULL;       //(8)将指针置为空,避免不安全访问
exit (0);

[root@localhost yangzongde]# gcc -o malloc_example malloc_example.c  //编译
[root@localhost yangzongde]# ./malloc_example       //运行
9   8   7   6   5   4   3   2   1   0
在以上程序中,(1)句中包含stdio.h头文件,从而在后面可以调用printf()函数。(2)句中包含stdlib.h头文件,其是malloc()函数的头文件。(3)句为函数的入口位置,此处采用Linux下编程标准,返回值为int型,argc为参数个数, argv[]为参数,envp[]存放的是所有环境变量。(4)句动态分配了10个整型存储区域,此语句可以分为以下几步。


① 分配10个整型的连续存储空间,并返回一个指向其起始地址的整型指针。


② 把此整型指针地址赋给array。


③ 检测返回值是否为NULL。


(5)、(6)句为数组赋值并打印输出,以免内存泄漏。(7)句调用free()函数释放内存空间。(8)句将一个NULL指针传递给array,虽然在很多情况下可以不用此句,但这样处理可以避免此指针成为野指针。


在C++中,使用new和delete运算符来实现内存的分配和释放,使用new/delete运算符实现内存管理比使用malloc/free函数更有优越性。new/delete运算符定义如下:


static void* operator new(size_t sz);     //new运算符
static void  operator delete(void* p);      //delete运算符
下面是一段C++程序代码:


void UseNewDelete(void)
{
Obj  *a = new Obj;           //申请动态内存并且初始化
//…
delete a;                   //清除并且释放内存
}
下面详细介绍C++中new/delete运算符的使用方法。


class A
{
public:
A()  {   cout<<"A is here!"<~A() {   cout<<"A is dead!"<private:
int i;
};
A* pA=new A;     //调用new运算符申请空间
delete pA;      //删除pA 
其中,语句new A完成了以下两个功能:


(1)调用运算符new,在自由存储区分配一个sizeof(A)大小的内存空间。


(2)调用构造函数A(),在这块内存空间上初始化对象。


当然,delete pA完成相反的两件事:


(1)调用析构函数~A(),销毁对象。


(2)调用运算符delete,释放内存。


由此可以看出,运算符new和delete提供了动态分配和释放存储区的功能。它们的作用相当于C语言的malloc()和free()函数,但是性能更为优越。使用new比使用malloc()有以下几个优点:


(1)new自动计算要分配给对象的内存空间大小,不使用sizeof运算符,简单,而且可以避免错误。


(2)自动地返回正确的指针类型,不用进行强制类型转换。


(3)用构造函数给分配的对象进行初始化。


但是,使用malloc函数和new分配内存的时候,本身并没有对这块内存空间做清零等任何动作。因此,申请内存空间后,其返回的新分配的内存是没有零填充的,程序员需要使用memset()函数来初始化内存。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值