当需要超过16GB的连续内存时,内存分配失败
Memory allocation failed when required more than 16GB contiguous memory
我的工作站有128GB内存。我无法分配占用(连续(内存超过~16GB的数组。但我可以分配多个阵列,每个阵列占用大约15GB。
样本代码:
#include <stdlib.h>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
int MM = 1000000;
int NN = 2200; // 2000 is okay, used ~16GB memory; 2200 produces Segmentation fault
double* testMem1d;
testMem1d = (double*) malloc(MM*NN*sizeof(double));
double* testMem1d1; // NN=2000, allocate another array (or two) at the same time is okay
testMem1d1 = (double*) malloc(MM*NN*sizeof(double));
cout << "testMem1d allocated" << endl;
cin.get(); // here is okay, only malloc but not accessing the array element
cout << "testMem1d[MM*NN-1]=" << testMem1d[MM*NN-1]<< endl;
cout << "testMem1d1[MM*NN-1]=" << testMem1d1[MM*NN-1]<< endl;
// keep running and check the physical memory footprint
for (int tt=0;tt<1000;tt++)
{
for (int ii=0; ii<MM*NN; ii++)
{
testMem1d[ii]=ii;
testMem1d1[ii]=ii;
}
cout << "MM=" << MM << ", NN=" << NN << ", testMem1d[MM*NN-1]=" << testMem1d[MM*NN-1]<< endl;
}
}
如果这不是一个基本问题,请忽略我在c++中使用malloc((。(是吗?(出于其他原因,我需要/想要使用malloc((。
一些观察结果:(1( 可以分配多个阵列,每个阵列都小于15GB(2( 只需执行malloc((即可"分段故障";当访问数组元素时。
我认为可能有一些系统设置限制了内存分配。从";ulimit-a";一切似乎都很好。由于程序可以访问64位虚拟地址空间,我找不到任何只限制连续内存分配的原因。
操作系统:Ubunt 16.04。我用mcmodel=large尝试了g++和icc。这似乎无关紧要。
uname -a
Linux 4.4.0-143-generic #169-Ubuntu SMP Thu Feb 7 07:56:38 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 515031
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) unlimited
cpu time (seconds, -t) unlimited
max user processes (-u) 515031
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
编辑:
(1( mallc((实际返回NULL[到mcleod_ideafix]
(2(
free -m
total used free shared buff/cache available
Mem: 128809 18950 107840 1129 2018 107910
Swap: 974 939 35
乘法MM*NN*sizeof(double)
是左关联的,因此它作为(MM * NN) * sizeof(double)
发生。在具有32位int
的平台上,具有等式MM * NN
的CCD_3等于不能在32位int
中表示的2200000000
,并且溢出(并且发生未定义的行为(和缠绕,从而产生-2094967296
。然后,该值被提升为与sizeof(double)
共同的类型,即size_t
。这是一种有符号类型到无符号类型的转换,其中有符号值不能用无符号类型表示,因此转换是由实现定义的。在二进制补码中用64位CCD_。然后这个值乘以sizeof(double)
,我假设它等于8
,它多次溢出(这是安全的,size_t
无符号(,得到18446744056949813248
字节。您的机器没有那么多内存,所以malloc
返回NULL。
这就是为什么将sizeof
作为malloc
调用中的第一个操作数是好的:
malloc(sizeof(double) * MM * NN);
在这种情况下,操作数将在乘法之前被提升到CCD_。
但这还不够,因为在testMem1d[MM*NN-1]
和ii<MM*NN
中仍然会发生溢出。因此,您应该将MM
和NN
的类型更改为具有足够位来保存结果的类型。
size_t MM = 1000000;
size_t NN = 2200;
或者在每次可能溢出的乘法运算之前,将值强制转换为正确的类型。
请注意,语句cout << "testMem1d[MM*NN-1]=" << testMem1d[MM*NN-1]<< endl; cout << "testMem1d1[MM*NN-1]=" << testMem1d1[MM*NN-1]<< endl;
正在读取未初始化的内存。
在C++中更喜欢使用new
。
- Win32编译器选项和内存分配
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 当需要超过16GB的连续内存时,内存分配失败
- 尝试摆脱任何堆内存分配
- 以下代码执行哪种内存分配(动态或静态)?
- 开放 CV 中的动态内存分配,用于视频处理
- 为什么类和 main() 函数中也有动态内存分配
- 使用 NTAllocateVirtualMemory 和 GetProcAddress 的内存分配问题不起作用
- C++:矢量分配器行为、内存分配和智能指针
- 介于 [固定数组] 和 [带内存分配的指针] 之间的性能
- Linux C++ 中的页面对齐内存分配
- 整数内存分配/释放
- 将内存分配返回值强制转换为 TYPE 数组
- C++程序什么都不做,但瓦尔格林德显示内存分配
- 给定特定内存地址的数组的动态内存分配
- 如何完成内存分配
- 我刚刚了解了C++中的动态内存分配
- 在先前调用 string::find 后添加内存分配和内存集会导致它返回 npos.为什么?
- 对于堆上的页面对齐内存分配是否有任何优化或不同的 API?
- 无法删除布尔动态内存分配