我需要创建一个大小为10000x100000的矩阵。我的RAM是4GB。它一直工作到第25次迭代(调试),但在第25次迭代后,我得到一个错误“错误分配”但是只使用了25%的RAM,这意味着问题与内存无关。那我该怎么办?
编辑:
int **arr;
arr=new int*[10000];
for(i=0;i<10000;i++)
arr[i]=new int[100000];
我的分配在上面。
答案 0 :(得分:1)
如果您正在为x64进行编译,那么您应该没有任何问题。
如果你正在编译x86(最有可能),你可以启用/LARGEADDRESSAWARE
链接器标志,如果你正在使用Visual C ++,或类似的其他编译器。对于Visual C ++,该选项也可以在链接器中找到 - &gt;系统 - &gt;在IDE中启用“大地址”属性。
这会在生成的EXE文件中设置一个标志,告诉操作系统该代码可以处理超过2 GB的地址。在x64 Windows(您的情况)上运行这样的可执行文件时,操作系统为其提供了4 GB的地址空间,而不是通常只有2 GB。
我在我的系统上测试了你的代码,Windows 7 x64,8 GB,使用链接器标志用Visual C ++ Express 2013(当然是x86)编译,代码运行良好 - 分配了大约4 GB而没有错误。< / p>
无论如何,第25次迭代太快而无法失败,无论它在哪里运行以及如何编译(大约10 MB),所以那里还有其他问题。
顺便说一下,HEAP
链接器选项在这种情况下没有帮助,因为它不会增加最大堆大小,它只是指定最初要保留多少地址空间以及要增加的块数提交的RAM量。简而言之,它主要用于优化目的。
答案 1 :(得分:0)
可能的解决方案是使用您的硬盘。 只需打开一个文件并存储您需要的数据。 然后只需将所需数据复制到缓冲区。 即使你成功地在堆上分配了这么多的数据 你将使用大多数时候不太可能使用的数据来重载堆。 最终,您可能会耗尽空间,这将导致性能下降或意外行为。 如果您担心使用硬盘驱动器可能会对您的问题产生影响,那么考虑程序解决方案是合适的。如果您可以在任何给定时刻生成所需的数据而不是存储它,您也可以解决您的问题。
答案 2 :(得分:0)
如果您正在使用VS,那么您可能想要尝试HEAP链接器选项并确保编译x64位目标,否则您将耗尽地址空间。物理内存的大小不应该是一个限制因素,因为Windows可以使用页面文件来提供额外的内存。 但是,从性能的角度来看,分配这种大小的矩阵可能是一个可怕的想法。也许你应该考虑使用备用矩阵,或者(按照LifePhilPsyPro的建议)按需生成数据。
答案 3 :(得分:0)
对于分配极大的缓冲区,最好使用操作系统服务将页面映射到地址空间而不是new / malloc。
您正尝试分配超过4GB。