![](/img/trans.png)
[英]Combining a C# and C++ project works for x86 and x64 but not for ARM
[英]C++ Array size x86 and for x64
一个简单的问题,我正在编写一个需要打开大图像文件(8kx8k)的程序,但是我对如何初始化大数组以将图像保存在c ++中感到有些困惑。
我一直在尝试这样的事情:
long long SIZE = 8092*8092; ///8096*8096
double* array;
array = (double*) malloc(sizeof(double) * SIZE);
if (array == NULL)
{
fprintf(stderr,"Could not allocate that much memory");
}
但是有时我的NULL检查不能捕获未初始化的数组,为什么?
另外,即使在具有12 GB RAM的x64机器上运行,我也不能初始化超过2个或3个数组。
我真的希望不必使用数组的各个部分。 欢迎任何帮助。
谢谢。
您没有遇到数组大小问题。 8K * 8K仅为64M。 即使是64M的双打(sizeof == 8)也不是问题。 仅需要512 MB。 现在,一个32位应用程序(无论它在何处运行)都应该能够分配其中的一些。 不是8,因为操作系统通常需要为其自身保留一些空间(通常略大于2GB),有时在内存碎片时甚至不需要3。
“ malloc失败但未返回NULL”的行为是Linux配置错误,已通过# echo 2 > /proc/sys/vm/overcommit_memory
修复
malloc()不会初始化内存,它只是保留它。 您将必须显式初始化它,例如通过string.h的memset()进行初始化:
array = (double*) malloc(SIZE * sizeof(double));
if (array) memset(array, 0, SIZE * sizeof(double));
但是,在C ++中,应使用new而不是malloc :
double* array = new double[SIZE];
if (!array) {
cerr << "Could not allocate that much memory" << endl;
}
for (int i=0; i<SIZE; i++) array[i] = 0.0;
关于大小:每个这样的阵列为512 MB。 您是否确定需要双精度(这意味着图像具有64位像素深度)? 也许花车就足够了? 那将使内存占用减少一半。
如果运行的是32位操作系统,则可能会遇到2GB的每个进程地址空间限制。 拥有数百MB的系统库和其他内容,以及2或3个512MB的阵列,将轻松获得2GB。 64位操作系统将为您提供帮助。
您是将应用程序编译为32位应用程序(如果使用的是Visual Studio中的默认设置)还是64位应用程序? 如果将其构建为64位应用程序,则不会有麻烦。
malloc分配(保留内存并返回一个指针),calloc初始化(将全零写入该内存)。
似乎在C运行时堆中没有这样大小的连续内存块(〜500Mb)。 不要将文件复制到内存中,而是尝试将映像映射到进程地址空间中。 您只能映射文件的必要部分。
正如一个侧面说明:虽然你不想理会整个图像在内存不是马上,还有理由不这样做。 也许考虑一个抽象,它允许您仅将当前所需的块保留在内存中。 然后可以编写程序代码,就好像忽略内存问题一样。
我真的希望不必使用数组的各个部分。 欢迎任何帮助。
您是否研究过内存映射文件?
我建议使用压缩。 解压缩您需要在代码中随时处理的部分,并在完成部分后对其进行压缩。
第二个建议:将代码写入过载内存指针“ operator +”和“ operator-”,以便可以使用非连续的内存缓冲区。 使用较小的内存缓冲区可使代码比连续的较大缓冲区更稳定。 我已经经历过并写了一些运算符重载,请参阅http://code.google.com/p/effoaddon/source/browse/trunk/devel/effo/codebase/addons/mem/include/mcur_i.h例。 当我在x86_64上测试47G malloc()系统内存时,每个malloc()调用仅分配1G,因此我总共分配了47个内存块。 编辑:虽然如果我尝试仅使用一个malloc()分配尽可能多的内容,但我在48G系统上只能获得30G的存储空间,比如说不到70%,那是因为每个malloc()请求的缓冲区更大,管理内存也更多您知道,由系统/ libc本身消耗的内存被称为mlock(),以防止分配的内存被换出到磁盘上。
第三个:尝试posix文件映射,每个图像映射到内存。
顺便说一句:尽管编写c ++,调用malloc()比new()更稳定,因为当内存紧张时,new()倾向于抛出异常,而不是返回NULL。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.