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

我在玩耍以了解可以分配多少内存。 最初我认为可以分配的最大内存等于物理内存(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

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

char * p1 = new char[644108290] ;
delete p1;

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

malloc可以分配的最大内存

我认为它一定是使用虚拟内存。所以我测试了免费交换内存的代码,它也工作。

char * p1 = new char[2428497920] ;
delete p1;

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

char * p1 = new char[3072606208] ;
delete p1;

但是这段代码没有抛出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;

输出节目

Size of array p = 3072606208
Size of array p1 = 4072606208
Size of array p2 = 777638912

你能帮我理解这里发生了什么吗? 为什么它允许在编译时分配内存,而不是动态分配内存。 在分配编译时间时, pp1如何分配比swap更多的内存以及可用的RAM内存。 p2失败的地方。 这是如何工作的。 这是一些未定义的行为或操作系统特定的行为。 谢谢你的帮助。 我使用Ubuntu 12.04和gcc 4.6.3。


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

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

最后, sizeof()是在编译时计算的,当编译器不知道OS将在以后做什么时。 所以它只会告诉你对象的预期大小。

如果您尝试在每种情况下将内存memset为0,您会发现事情会表现得非常不同。 另外,你可能想尝试一下calloc ,它将它的内存归零。


有趣的是......有一件事要注意:当你写作的时候

char p[1000];

您在堆栈上分配(保留)100个字节。

当你写

char* p = malloc(100);

你在堆上分配100个字节。 巨大差距。 现在我不知道为什么堆栈分配正在工作 - 除非编译器将[]中的值作为int读取,并因此分配更小的块。

大多数操作系统都不会分配物理内存,它们会为您提供虚拟地址空间中的页面,这些空间在您使用之前一直未使用(并因此未分配),然后CPU的内存管理器单元将为您提供内存要求。 尝试写入你分配的字节,看看会发生什么。

此外,至少在Windows中,当您分配一块内存时,您只能保留OS可用的最大连续块 - 因为内存被重复分配碎片化,您可以减少malloc的最大侧块。 我不知道Linux是否也有这个问题。


这两个程序之间有很大的区别:

program1.cpp

int main () {
   char p1[3072606208];
   char p2[4072606208];
   char p3[5072606208];

   std::cout << "Size of array p1 = " << sizeof(p1) << std::endl;
   std::cout << "Size of array p2 = " << sizeof(p2) << std::endl;
   std::cout << "Size of array p3 = " << sizeof(p3) << std::endl;
}

program2.cpp:

char p1[3072606208];
char p2[4072606208];
char p3[5072606208];

int main () {

   std::cout << "Size of array p1 = " << sizeof(p1) << std::endl;
   std::cout << "Size of array p2 = " << sizeof(p2) << std::endl;
   std::cout << "Size of array p3 = " << sizeof(p3) << std::endl;
}

第一个分配堆栈上的内存; 由于堆栈溢出,将会出现分段错误。 第二个没有太大的作用。 那个记忆还不完全存在。 它是以数据段的形式未被触及的。 让我们修改第二个程序,以便触及数据:

char p1[3072606208];
char p2[4072606208];
char p3[5072606208];

int main () {

   p1[3072606207] = 0;
   p2[3072606207] = 0;
   p3[3072606207] = 0;

   std::cout << "Size of array p1 = " << sizeof(p1) << std::endl;
   std::cout << "Size of array p2 = " << sizeof(p2) << std::endl;
   std::cout << "Size of array p3 = " << sizeof(p3) << std::endl;
}

这不会为堆或堆栈上的p1p2p3分配内存。 该记忆存在于数据段中。 它是应用程序本身的一部分。 这有一个大问题:在我的机器上,这个版本甚至不会链接。

链接地址: http://www.djcxy.com/p/86495.html

上一篇: Maximum memory that can be allocated dynamically and at compile time in c++

下一篇: If free() knows the length of my array, why can't I ask for it in my own code?