内存管理:new/delete操作符与malloc()/free()函数

本文在本人赛迪博客上同期刊出http://itrock.blog.ccidnet.com/blog-htm-do-showone-uid-255426-type-blog-itemid-1613979.html  转载请注明出处

 

    C++相比C#令人头痛也同样令痴迷于C++的程序员快慰的一点是对于指针的操作和对于内存的分配。不熟练的程序开发者往往会因指针和内存的不当操作而碰到许多问题。而娴熟的程序员却可以自如地定义指针的行为,自主分配/回收内存,使得程序代码的执行效率更高。

    内存的分配/回收有两种机制。其一是malloc()/free()函数,其二是new/delete运算符。malloc()/free()是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。由于前者是标准库函数,后者是运算符,这决定了他们在实现内存管理时的差别所在。

    对于非内部数据类型的对象而言,光用malloc()/free()无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc()/free()是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc()/free()。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数,而是在C++中强化了的运算符。

    对于内部数据类型来说,由于内部数据类型的“对象”没有构造与析构的过程,对它们而言malloc()/free()和new/delete是等价的。既然new/delete的功能完全覆盖了malloc()/free(),为什么C++不把malloc/free淘汰出局呢?这是因为C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。

    如果用free释放“new创建的动态对象”,那么该对象因无法执行析构函数而可能导致程序出错。如果用delete释放“malloc申请的动态内存”,理论上讲程序不会出错,但是该程序的可读性很差。所以new/delete必须配对使用,malloc/free也一样。

    简而言之:

    1.new/delete在实现上其实调用了malloc()/free()函数。

    2.new除了分配内存,还要调用构造函数;而malloc()只是分配内存。

    3.delete除了回收内存,还要调用析构函数;而free()只是回收内存。

    4.new/delete是C++中(而不是C中)的运算符,而malloc()/free()是C++/C中均有的函数。

    5.对于内部数据类型而言malloc()/free()和new/delete的作用等价;而对于需要构造和析构的非内部对象类型而言内存管理只能通过new/delete操作符。

    6.malloc()/free(),new/delete均应成对使用,防止内存泄漏。

 

    下面所讲的案例是作者在使用new/delete运算符时遇到的问题,发现网上有好多网友也遇到过这个问题,结合网路上的一些解答,现总结出来。

 

    下面是一段简短的程序代码:

    unsigned int ID;

    char * str=new char[3];

    for(ID=100;ID<110;++ID)

    {

       itoa(ID,str,10);

       printf("%s ",str);

    }    

    delete []str;

    该程序编译可以通过,但运行时会报错。原因在于我们申请的字符串str是三个字符长度,而三位数的整型数ID转换为字符串时为4个字符(3个数字,末尾一个空字符),所以实际上程序运行中写入str内存的内容容量大于str开辟的内存容量,这导致在用delete回收str内存时系统报错。这里如果把str字符串的长度开辟为4个字符长度,则程序是正确的。

 

     下面是一个网友所碰到的问题,因为具有代表性,所以也贴上来:

     char *  p   =   new char;   

     int  *  i   =   new int;   

     p   =   "hi";   

     cout<< *p <<endl;   

     *i   = 123 ;   

     delete   i;   // 为何delete整型指针是正确的

     delete   p;   // 而delete字符串指针式错误的?

 

     关于这个问题,一个网友给出了合理的解释:出现这个错误的原因不是memory overflow而是memory lost。首先char* p = new char返回的是一个字节的指针;其次 p = "hi"把一个常量字符串的指针赋给了p,会导致p原来指向的内存被忽略,当程序最后用delete p去回收内存时实际上并不是回收由new所分配出来的那部分内存,结果造成内存泄漏。另外由于此时p指向了一个字符串常量"hi",语句delete p属于非法操作。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值