我想创建一个具有UINT_MAX
个索引的char arr[UINT_MAX]; // Compiler claims array size cannot be negative
个数组。由于某些原因,这非常困难。我尝试过以下方法:
char* const arr = calloc(UINT_MAX, sizeof(char)); // Runs but seg fault when accessed
char* const arr = malloc(sizeof(char) * UINT_MAX); // arr is NULL
malloc/calloc
我不明白发生了什么。这是我的HEAP尺寸太低了吗?如果是这样,我该如何增加它? malloc
可以不处理那种性质的块吗?我在calloc
或#We want to plot the mean for the whole region so we need a mean of all the lats and lons
CCCma_mean = CCCma.collapsed(['latitude', 'longitude'], iris.analysis.MEAN, weights=CCCma_grid_areas)
CRU_mean = CRU.collapsed(['latitude', 'longitude'], iris.analysis.MEAN, weights=CRU_grid_areas)
UDel_mean = UDel.collapsed(['latitude', 'longitude'], iris.analysis.MEAN, weights=UDel_grid_areas)
#PART 4: PLOT LINE GRAPH
#limit x axis
plt.xlim((1990,2008))
#assign the line colours
qplt.plot(CCCma_mean.coord('year'), CCCma_mean, label='CanRCM4_ERAINT', lw=1.5, color='blue')
qplt.plot(CRU_mean.coord('year'), CRU_mean, label='Observed_CRU', lw=2, color='black')
qplt.plot(UDel_mean.coord('year'), UDel_mean, label='Observed_UDel', lw=2, color='black', linestyle='--')
#create a legend and set its location to under the graph
plt.legend(loc="upper center", bbox_to_anchor=(0.5,-0.05), fancybox=True, shadow=True, ncol=2)
#create a title
plt.title('Mean Near Surface Temperature for Malawi 1989-2008', fontsize=11)
#add grid lines
plt.grid()
#save the image of the graph and include full legend
#plt.savefig('ERAINT_Temperature_LineGraph_Annual', bbox_inches='tight')
#show the graph in the console
iplt.show()
API页面中找不到任何有用的内容。
这个问题适用于C和C ++。
Windows 7 64位,16GB RAM,CMake 3.6.1,GCC 7.11.1,并在CLion 64位上编译。
答案 0 :(得分:5)
首先,我要指出的是,可以和应使用errno
来检查API调用失败的原因。
现在,让我们检查你的尝试:
堆叠分配 - char arr[UINT_MAX]
您正尝试在堆栈上分配4294967295字节,这是不可行的,因为操作系统会将堆栈大小限制为更小的大小。您可以尝试使用此manual中指定的API来操作它。
<强>的malloc 强>
在大多数情况下,堆分配会因单一原因而失败:操作系统无法分配足够大的连续内存。
并不是说你的系统没有4GB的可用内存,但完全有可能没有一大块连续的内存适合你的请求。所以,就像malloc
MSDN page指出的那样:
malloc
返回指向已分配空间的void指针,如果没有足够的可用内存,则返回NULL
<强>释放calloc 强>
malloc
和calloc
使用相同的底层机制,因此如果一个失败,您应该期望第二个失败。请参阅calloc
remarks
关于Linux平台上malloc
的有趣事实
根据评论的要求,我将在Linux上指出有关malloc
实施的一些有趣事实,因为它有很大不同!
首先,Linux明确指出它使用乐观的内存管理算法:
默认情况下,Linux遵循乐观的内存分配策略。这意味着当malloc()返回非NULL时,无法保证内存确实可用。如果事实证明系统内存不足,那么一个或多个进程将被OOM杀手杀死
这意味着内存并非实际拥有并专用于被叫方,而是操作系统希望在他需要时可以为他提供内存,如果它不是&#39 ; t,它恢复了一些讨厌的手段。
编辑:正如@Basile Starynkevitch正确指出的那样,这种机制依赖于内存过量使用开关,默认情况下已启用, 但是can be disabled。
答案 1 :(得分:2)
这是特定于操作系统的。但是,不检查malloc
或calloc
的失败导致undefined behavior(例如您的calloc
的段错误)并且总是错误(并且是基本的)错误你应该避免这样做)。请记住,malloc
和calloc
可能会失败,并且在您请求或已经使用大量内存时更有可能失败(因为virtual memory是有限的资源)。请注意,sizeof(char)
始终为1。
以下计划
// file hatefiend.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
int main(int argc, char**argv) {
size_t sz = (argc>1)?(size_t)(atol(argv[1])):UINT_MAX;
char *ad = malloc(sz);
if (!ad) {perror("malloc"); exit(EXIT_FAILURE); };
for (unsigned long ix=0; ix<(unsigned long)sz; ix += 1024)
ad[ix] = (char)(' ' + (ix & 0x3f));
printf ("ad=%p sz=%zd\n", ad, sz);
/// the code below is optional and Linux specific,
/// remove it or adapt it for Windows
char cmd[80];
snprintf(cmd, sizeof(cmd), "pmap %d", (int)getpid());
printf ("command: %s\n", cmd);
fflush(NULL);
int bad = system(cmd);
if (bad) return EXIT_FAILURE;
return 0;
}
在具有16 GB RAM的Linux / Debian / x86-64笔记本电脑系统上运行良好(并且gcc -Wall -O hatefiend.c -o hatefiend
移除ad
后不会对其进行优化,因为它在printf
中使用给予:
% ./hatefiend
ad=0x7fc3d5c09010 sz=4294967295
command: pmap 31644
31644: ./hatefiend
000056355b8e3000 4K r-x-- hatefiend
000056355bae3000 4K r---- hatefiend
000056355bae4000 4K rw--- hatefiend
000056355c3de000 132K rw--- [ anon ]
00007fc3d5c09000 4194308K rw--- [ anon ]
00007fc4d5c0a000 1612K r-x-- libc-2.24.so
00007fc4d5d9d000 2048K ----- libc-2.24.so
00007fc4d5f9d000 16K r---- libc-2.24.so
00007fc4d5fa1000 8K rw--- libc-2.24.so
00007fc4d5fa3000 16K rw--- [ anon ]
00007fc4d5fa7000 140K r-x-- ld-2.24.so
00007fc4d6190000 8K rw--- [ anon ]
00007fc4d61c7000 12K rw--- [ anon ]
00007fc4d61ca000 4K r---- ld-2.24.so
00007fc4d61cb000 4K rw--- ld-2.24.so
00007fc4d61cc000 4K rw--- [ anon ]
00007ffe8f561000 132K rw--- [ stack ]
00007ffe8f5b7000 12K r---- [ anon ]
00007ffe8f5ba000 8K r-x-- [ anon ]
total 4198476K
从pmap(1)的输出可以看出,确实已经分配了内存。
您可以轻松地为您的Windows系统调整:删除<unistd.h>
并更改snprintf
以构建显示virtual address space的命令,即替换{某些特定于Windows的utility {1}};或者只删除命令的所有构建,即pmap
及其用法......
所以帮自己一个忙:安装和使用Linux(可以看作是一种挑衅或一种有用的提示)。 Windows 可能 cmd
或malloc
失败。或者努力理解为什么发生了这种情况,并且可能在系统中配置以使巨大的calloc
成功。如何做到这一点是一个系统管理员问题,超出Stack Overflow的范围(但你可以问
SuperUser)。小心memory overcommitment(我通常禁用它)。
我的HEAP尺寸是否太低?如果是这样,我该如何增加它?
您可能希望增加虚拟内存或虚拟地址空间限制(因为heap内存是malloc
给出的内存。如何做到这一点是一个系统管理员问题(应该在SuperUser上询问),你需要提供更多细节才能获得帮助。
在评论中你提到你的malloc
是一个32位整数(这让我很惊讶很多; 你是在64位模式编译吗? on我的Linux / x86-64机器是64位,如某些size_t
或uint64_t
)。然后我相信你想要的东西在你的系统中是不可能的(因为unsigned long
实现需要一些额外的空间 - 例如一些额外的单词用于簿记 - 并且可能计算一些内部malloc
的开销。 ..)
请记住,this malloc(不是非常有用,但非常快)遵循C标准的字母。
但是我相信你有一些XY problem,你可以实现你的目标(没有说明)。这就是为什么激励问题对Stack Overflow很重要。也许将size_t
声明为static variable可能会有所帮助:arr
....但请阅读this的缺点。
答案 2 :(得分:0)
不确定为什么你需要那么多char数组,但无论如何
char arr[UINT_MAX];
这对于堆栈大小来说太大了。没有编译器分配这么多堆栈大小。您可以在使用标记-stack
进行编译时增加堆栈大小,但它仍然仅限于您的系统配置。
你可以通过调用命令ulimit -s
来检查你的限制,并在尝试之前将其设置为无限ulimit -s unlimited
。但是它仍然可能失败。
malloc
返回NULL,因为它无法分配您要求的内存和calloc
的内存。
增加虚拟内存或物理内存或两者以获取此内存。即使内存可用,它也可能会碎片到一定程度,系统无法满足您的请求。