可以在c ++中动态分配并在编译时分配的最大内存

For*_*ner 8 c++ ubuntu memory-management new-operator

我正在玩,了解可以分配多少内存.最初我认为可以分配的最大内存等于物理内存(RAM).我通过运行命令检查了Ubuntu 12.04上的RAM,如下所示:

~$ free -b
             total       used       free     shared    buffers     cached
Mem:    3170848768 2526740480  644108288          0  265547776 1360060416
-/+ buffers/cache:  901132288 2269716480
Swap:   2428497920          0 2428497920
Run Code Online (Sandbox Code Playgroud)

如上所示,总物理内存为3Gig(3170848768字节),其中只有644108288字节是空闲的,所以我假设我最多只能分配这么多内存.我通过编写下面只有两行的小程序来测试它:

char * p1 = new char[644108290] ;
delete p1;
Run Code Online (Sandbox Code Playgroud)

由于代码运行完美,这意味着它成功分配了内存.此外,我尝试分配的内存大于可用的物理空闲内存,但它没有抛出任何错误.然后每个问题

malloc可以分配的最大内存

我认为它必须使用虚拟内存.所以我测试了免费交换内存的代码,它也工作.

char * p1 = new char[2428497920] ;
delete p1;
Run Code Online (Sandbox Code Playgroud)

我试图分配免费交换加上可用RAM字节的内存

char * p1 = new char[3072606208] ;
delete p1;
Run Code Online (Sandbox Code Playgroud)

但是这次代码失败了抛出bad_alloc异常.为什么代码这次不起作用.

现在我在编译时在新程序中分配了内存,如下所示:

char p[3072606208] ;
char p2[4072606208] ;
char p3[5072606208];
cout<<"Size of array p = " <<sizeof p <<endl;
cout<<"Size of array p2 = " <<sizeof p2<<endl;
cout<<"Size of array p2 = " <<sizeof p3;
Run Code Online (Sandbox Code Playgroud)

输出显示

Size of array p = 3072606208
Size of array p1 = 4072606208
Size of array p2 = 777638912
Run Code Online (Sandbox Code Playgroud)

你能帮我理解这里发生的事吗?为什么它允许在编译时分配内存,而不是动态分配内存.当分配编译的时候怎么来的p,并p1能分配的内存比交换以及免费的RAM内存更大.哪里p2失败了.这究竟是如何运作的.这是一些未定义的行为或操作系统特定的行为.谢谢你的帮助.我使用的是Ubuntu 12.04和gcc 4.6.3.

Mik*_*one 6

在您使用它们之前,内存页面实际上并未映射到您的程序.所有这些malloc都是保留一系列虚拟地址空间.在您尝试读取或写入虚拟页面之前,不会将物理RAM映射到这些虚拟页面.

即使您分配全局或堆栈("自动")内存,在您触摸它们之前也没有物理页面的映射.

最后,sizeof()在编译时进行评估,此时编译器不知道操作系统稍后会做什么.所以它只会告诉你对象的预期大小.

如果你memset在每种情况下尝试将内存设置为0,你会发现事情会有很大的不同.此外,您可能想尝试calloc,它会将其内存归零.