new操作符在vc.net下使用,看帮助说的是默认仍然是失败返回0值,如果包含了诸如<new>等标准库,失败时将抛出std::bad_alloc异常,又说除了包含标准库外也可以显式的添加thrownew.obj,我的英文比差还差,到这部分已经看的满天星斗了,反正最后下面的代码我始终无法让他正常的失败以检验到底是返回0还是抛出异常:
(这是在一个类的构造函数中的代码)MyClass::MyClass()
: m_p1(NULL)
, m_p2(NULL)
, m_p3(NULL)
{
  try{
       m_p1=new unsigned char[size1];
       m_p2=new unsigned char[size2];
       m_p3=new MyClass2;
  }
  catch(std::bad_alloc&)
  {
     Beep(2000,100);
  }  首先我把size1改的很大,希望他会异常,但是该死的2000到了size1=800M的时候仍然成功的分配给了我内存,当然了硬盘一顿狂响。再大的时候程序弹处一个出现错误的对话框然后终止了,没有std::bad_alloc被捕捉。
  然后我将try里的第一句改成:while(1) {m_p1=new unsigned char[size1];}运行的结果是硬盘一阵轰鸣,大约10秒后系统告诉我内存不足将增加虚拟内存页,确定,又是程序弹出一个出现错误的对话框然后终止了,没有std::bad_alloc被捕捉。
  然后将循环内加上if(NULL==m_p1) AfxMessageBox("asdfad");同样也是即没有我定义的对话框弹出也没有std::bad_alloc被捕捉。
  然后将new的形式改成new(std::nothrow)重复上面的实验效果一样。
  然后我将<new>包含,重复以上试验,效果一样。
  最后,发疯。另外,发现std::set_new_handler(NULL)如果在上面的构造函数里使用(那个类生成唯一的一个全局实体)会发生非法,其他地方就没有关系,不知道何解。  我只是想按照标准C++的特性使用new而已,咋就这么费劲呢,大家帮帮忙吧*@*

解决方案 »

  1.   

    #去掉#define new DEBUG_NEW
      

  2.   

    同意SeekTruth(鹤舞白沙)
    构造函数里面不会抛出异常。
      

  3.   

    对于32位以上的应用程序而言,无论怎样使用malloc与new,几乎不可能导致“内存耗尽”。因为32位操作系统支持“虚存”,内存用完了,自动用硬盘空间顶替。
      

  4.   

    我是楼主,目前有些进展:还是在构造函数中,在包含了<new>的情况下,如下代码:while(1)
    {
      m_p1=new(std::nothrow) unsigned char[1000000];
      if(NULL==m_p1)
      { 
         AfxMessagebox("dasdfasdfsa");
      }
    }在循环到八百多的时候终于弹出了对话框"dasdfasdfsa",并且这个反应是确定的,虽然仍疑惑不解但是终于有一个可以确定结果的方式供我使用了。
    确实2000几乎能无限的提供内存,程序运行时任务管理器中可看到内存数直线上升,但是也是有个限度的,我的机器大约在1G多的时候就不行了。希望哪位对动态内存分配有研究的朋友出来指点一下吧,即使给个正确结论也好。构造函数里可以抛出异常。
      

  5.   


    构造函数不能抛出异常!!!!如果有异常抛出,你的AfxMessagebox("dasdfasdfsa");就永远不会被执行,因为它会跳到异常处理程序。
      

  6.   

    构造函数不能抛出异常
    同样ing
      

  7.   

    楼上不要激动,构造函数可以抛出异常,构造函数中也可以捕捉异常。而且,我的代码写的是new(std::nothrow),这个版本的new无论成功失败都不会抛出异常,而且注意我是一直在构造函数里捕捉不到new抛出的异常,这跟构造函数能不能抛出异常没有关系,况且,你可以想一想,如果构造函数不能抛出异常也不能捕捉异常那唯一的结果是任何构造必须成功。我的问题是在VC.NET环境下如何按照标准C++的特性实现new,仅此而已,高人帮忙。
      

  8.   

    while(1)
    {
      m_p1=new(std::nothrow) unsigned char[1000000];
      if(NULL==m_p1)
      { 
         AfxMessagebox("dasdfasdfsa");
      }
    }
    还是不太懂你什么意思,只要new成功就不会有AfxMessagebox("dasdfasdfsa");既是不成果m_p1是不是等于NULL呢?
      

  9.   

    呵呵,AthlonxpX86(一滴水)有幸又和你相逢了。
    是的,我那段代码意思就是new(std::nothrow)可以肯定在失败时返回NULL,弹出对话框是为了知道分配内存失败了,没别的意思。重要的是new(std::nothrow)在失败时返回NULL是可以确定的,这样我在程序中就可以放心使用而不必担心出现意想不到的情况了。
    当然,对于没有足够内存这种系统级别的非正常情况,即使知道了也只能重新启动计算机而已,但是总得确切的检测到啊。
    实际上,在程序中我实际要求的那点内存是不会分配不出的,我非要检查失败是因为这样心里舒服一些。但是,我真的想让new在失败时抛出异常,否则在看那些标准C++的书时会不停的担心,不知道这些标准C++的特性是否真的被编译器支持,郁闷。
      

  10.   

    内存大时我喜欢用::VirtualAlloc()