关于内存释放的问题 easy~?报错-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文

关于内存释放的问题 easy~?报错

爱吃鱼的程序员 2020-06-20 17:12:47 60

@中山野鬼 你好,想跟你请教个问题:为什么不可以连续释放内存 就像这样:

int *p = new int;

delete p;

delete p;

是不是内存是有标记的?然后再次释放会去检查这个标记,没有标记就报错了


分享到
取消 提交回答
全部回答(1)
  • 爱吃鱼的程序员
    2020-06-20 17:13:04

    C++的权当我不会。太违背理性的一种语言。哈哈。和C根本上就是一个原因。<divclass="ref">

    引用来自“中山野鬼”的评论

    C++的权当我不会。太违背理性的一种语言。哈哈。就Java的奇葩设计还有脸说啥纯粹?阉了还差不多。连个确定性析构都没有;存储都管不干净非得自欺欺人把具有类似union{Tobj;T ptr;}类型的玩意儿叫成什么“对象”还跟primitivetype势不两立;用类型擦除当泛型糊弄用户玩……根本就是罄竹难书嘛。这话有意思,不过容易引起战争,哈哈。。。。。。delete是释放内存还给操作系统,你已经释放了,操作系统就会回收,可能这个时候已经把它又分配给别人了,你就不能再操作它了。当然一般这部分空间还在你这个程序内部,如果你中间new了一个别的变量就分配给它了。所以一般delete完,就要把指针置空,避免出现野指针。至于你说的标记,这部分是操作系统实现的,可能是。谢谢啊

    C++不太清楚。

    对于C语言而言,在Linux中,当使用malloc分配内存的时候,返回的指针,它指向的内存地址之前的四个字节,记录了内存的大小(自己的电脑测试下来,记录的大小比分配的大小大9,应该是记录其他内容用的),同时Linux内存管理系统会标记内存已使用。当我们使用free的使用,系统会根据记录的内存大小来释放内存。这个时候,Linux的内存管理系统会标记内存已释放。

    当我们再次释放的时候,free会执行同样的操作,即根据传入的参数指向的内存地址之前的四个字节的大小来释放内存,这个时候Linux内存管理系统应该会出问题。

    因为free可以释放空指针,即NULL。所以,多次释放NULL,是可以的。这也是为什么建议释放后,置位NULL。可以避免doublefree导致的错误。

    对于C++,机制应该有些相似。仅供参考。

    C++的delete和free类似允许空指针值。受教了谢谢啊今晚做了一下测试,代码是这样的: 
    int
    psome=newint[10];
      deletepsome;
      psome[2]=10;
      int p=newint;
      p=900;
      deletep;
      for(inti=0;i<100;i++){
        sleep(1);//休眠1s
        cout<<p<<endl;
        cout<<psome-p<<endl;
      }
      return0;
    然后其结果是虽然p被释放了,但是我们还是可以访问
    p的内容,*p的结果还是900,而且psome与p的内存地址相隔就是12吧,好像是动态内存分配就是在一个区域内的。我是这样想的:每个独立的程序的动态内存是有固定的区域的,不知对不对啊
    回复<aclass='referer'target='_blank'>@catch2000:不管是C还是C++的实现都不需要指望操作系统的支持。没有操作系统照样有malloc/new。回复<aclass='referer'target='_blank'>@幻の上帝:因为不同的操作系统内存管理算法是不一样的,我们不能依靠它们。这里我提到的操作系统,不只是Linux与Windows的区别,还有Rtems,Vxworks,uc/OS,eCos,以及Contiki。我们不能期望它们能有什么相似的内存管理算法。毕竟C语言只是语言,内存管理是我们通过算法来实现的,不是语言的范畴了。回复<aclass='referer'target='_blank'>@catch2000:脱离具体实现无所谓什么堆区。对C++来说就叫freestorage。对于C来说连个正式的称呼都没有,只知道这里的对象具有allocatedstorageduration。靠具体实现的结果来解释是彻头彻尾的方法论错误。对于你这里的psome-p操作,是有风险的。在你的系统上是这样,但是在其他系统上不一定。没有指向同一数组(或者分配的内存)的指针,一般是要避免他们的大小比较和加减运算。因为这样的结果是未定义的。可以参见:《MISRAC2004》(这份文档是一个C安全子集)<divclass='ref'>

    引用来自“Stieven”的评论

    今晚做了一下测试,代码是这样的: 
    int
    psome=newint[10];
      deletepsome;
      psome[2]=10;
      int
    p=newint;
      *p=900;
      deletep;
      for(inti=0;i<100;i++){
        sleep(1);//休眠1s
        cout<< p<<endl;
        cout<<psome-p<<endl;
      }
      return0;
    然后其结果是虽然p被释放了,但是我们还是可以访问
    p的内容,*p的结果还是900,而且psome与p的内存地址相隔就是12吧,好像是动态内存分配就是在一个区域内的。我是这样想的:每个独立的程序的动态内存是有固定的区域的,不知对不对啊
    <divclass='ref'>

    引用来自“中山野鬼”的评论

    <divclass="ref">

    引用来自“中山野鬼”的评论

    C++的权当我不会。太违背理性的一种语言。哈哈。

    跟C类似,ISOC++规定在这种用法就是undefinedbehavior,不保证任何可预测的行为,后果自负。

    说白了还是责任分配问题。实现有权假定用户正确地遵守了约定不作死。

    具体细节具体实现管。没给出环境之前进一步纠结没意义。(因为ISOC++支持独立实现,你还没法让人假定操作系统的存在。)





    0 0
云计算
使用钉钉扫一扫加入圈子
+ 订阅

时时分享云计算技术内容,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。

推荐文章