繁体   English   中英

C ++数组大小x86和x64

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM