Exception C++/使用新的CLI内存分配引发异常

Exception C++/使用新的CLI内存分配引发异常,exception,memory-management,c++-cli,new-operator,Exception,Memory Management,C++ Cli,New Operator,我(我相信)在使用“new”分配内存方面有一个非常典型的问题。 下面是我使用的一段代码: float * _normals = NULL; try{ _normals = new float[_x*_y*_z*3]; }catch(System::Exception ^ e){ Windows::Forms::MessageBox::Show("Normals:\n" + e->Message); if(e->InnerException != null

我(我相信)在使用“new”分配内存方面有一个非常典型的问题。 下面是我使用的一段代码:

float * _normals = NULL;
try{

    _normals = new float[_x*_y*_z*3];
}catch(System::Exception ^ e){

    Windows::Forms::MessageBox::Show("Normals:\n" + e->Message);

    if(e->InnerException != nullptr && e->InnerException->Message != nullptr)
        Windows::Forms::MessageBox::Show("Details:\n" + e->InnerException->Message);

    _file->Close();

return 0;
}
我不知道你是否能从这段代码中分辨出来,但这是一个混合了托管和非托管代码的程序。我不知道这是否重要

现在,当我运行这段代码并尝试分配,比如说,256*256*128*3浮点数时,它会正常运行。当我使用492*492*442浮点数时,它会抛出一个“外部组件已抛出异常”异常。这大约是1.2GB,对吧。我的系统有6GB内存,可用内存约为3GB。你能从这些信息中看出问题吗?我能处理吗?我在某处读到关于程序内存空间的内容。也许程序内存不够?(如果你能启发我的话,我对这件事一无所知)

请询问您是否需要更多信息


提前感谢您

在64位操作系统上运行的32位Windows程序(Windows由C++-CLI表示)的地址空间为

  • 默认为2GB
  • 如果与
    /largeaddressware
    链接,则为4 GB。此标志也可以稍后通过
    editbin
    添加
您的问题是地址空间碎片。仅仅因为您只分配了(比如100MB),并不意味着您可以在2GB地址空间中再分配一个1.9GB块。您的新分配需要有连续的地址

例如,如果非LAA进程使用的DLL的加载地址位于
0x40000000
,则可以在其下方分配1GB块,或在其上方分配近1GB块,但不能分配大于1GB的单个块


最简单的解决方案是编译为64位。即使地址空间仍然是碎片化的,分配之间的开放空间也会大得多,不会给您带来问题。

您使用的是64位吗?默认情况下,32位的地址不能超过3 GB。@LaszloPapp,你不是说4GB吗?@ChrisJester-Young:已经删除了我的评论,尽管没有看到它是c++-cli(不管是什么),我会假设打字错误,因为这两个字符(&和^)是我键盘上的下两个字符更有趣的问题是为什么要分配这么大的内存块。可能需要注意的是,该算法在64位操作系统上运行的代码与此无关。重要的是您是否真正使用64位编译器构建了代码。它不会与默认项目设置一起使用,托管代码可以在任一模式下运行这一事实与C++/CLI无关,因为它会生成混合模式程序集。新操作员不是托管代码。
不会给您带来问题。
->如果是错误的,它可能会导致类似问题。真正的解决方案是我所建议的,重构算法。@LaszloPapp:我不相信他会在一个块中把它全部传递给OpenGL。但是为了避免在较小的子集中出现不满,整个事情需要连续进行。好吧,这是我的-1的价值,对不起(不,我没有给出前一个,不管你如何指责我幼稚的报复等等)。在不必像这样连续的情况下不加考虑地分配如此巨大的内存区域是一种非常糟糕的做法。@LaszloPapp:另外,你提出的一个潜在问题不是地址空间。我完全正确,在64位进程中,地址空间碎片不会导致问题。@LaszloPapp:请解释如何进行1.2GB不连续分配,以使任何1kB子集都是连续的。这是办不到的。(归纳证明表明整个块必须是连续的)使用单个连续分配有一定的优势,即使数据将仅在重叠批次中处理。