我想创建一个具有确切UINT_MAX索引数的数组.由于某些原因,这非常困难.我尝试过以下方法:
char arr[UINT_MAX]; // Compiler claims array size cannot be negativechar* const arr = calloc(UINT_MAX, sizeof(char)); // Runs but seg fault when accessedchar* const arr = malloc(sizeof(char) * UINT_MAX); // arr is NULL我不明白发生了什么.这是我的HEAP尺寸太低了吗?如果是这样,我该如何增加它?无法malloc/calloc处理那种性质的块?我发现没有什么有用malloc或callocAPI页面.
这个问题适用于C和C++.
Windows 7 64位,16GB RAM,CMake 3.6.1,GCC 7.11.1,并在CLion 64位上编译.
首先,我要指出的是,您可以而且应该使用它errno来检查API调用失败的原因.
现在,让我们检查你的尝试:
堆栈分配 -char arr[UINT_MAX]
您试图在堆栈上分配4294967295字节,这是不可行的,因为操作系统将堆栈大小限制为更小的大小.您可以尝试使用本手册中指定的API对其进行操作.
的malloc
在大多数情况下,堆分配将因单一原因而失败:操作系统无法分配足够大的连续内存.
这并不是说你的系统没有4GB的可用内存,但完全有可能没有一大块连续的内存适合你的请求.所以,就像malloc的MSDN页指出:
malloc返回指向已分配空间的void指针,如果没有足够的可用内存,则返回NULL
释放calloc
malloc并calloc使用相同的底层机制,因此如果一个失败,你应该期望第二个失败.参见备注部分calloc的MSDN页
有关mallocLinux平台的有趣事实
根据评论的要求,我将指出一些有关malloc在Linux上实现的有趣事实,因为它有很大不同!
首先,Linux特别指定它使用乐观的内存管理算法:
默认情况下,Linux遵循乐观的内存分配策略.这意味着当malloc()返回非NULL时,无法保证内存确实可用.如果事实证明系统内存不足,那么一个或多个进程将被OOM杀手杀死
这意味着内存并不是实际拥有并专用于被调用者,而是操作系统希望在他需要时可以为他提供内存,如果不需要,它会恢复到一些讨厌的手段.
编辑:正如@Basile Starynkevitch正确指出的那样,这种机制依赖于内存过量使用开关,它默认启用,但可以禁用.