malloc(-1):       windows 上会崩溃             linux上  不会崩溃

malloc(0):      windows       int*p=(int *)malloc(0) ;如果使用了这块内存eg:  *p=1;   再free(p) ;就会崩溃       

                          linux上       malloc申请 <=12字节的内存,都会分配出12字节大小的内存

                                             malloc申请  >12字节的内存,分配的内存会在12d的基础上每次增加8字节;(X-12)%8==0

                                          eg:   malloc申请内存大小              系统分配内存大小

                                                         0                                                    12

                                                        11                                                   12

                                                       12                                                    12

                                                       13                                                    20       

                                                      129                                                  132

另外,windows上求分配内存大小用_msize();Linux上用malloc_usable_size();  而不是sizeof()或strlen();

_msize()为windows下检测堆上动态分配的内存块的大小

malloc_usable_size为LINUX下进行检测的函数。

原因:

当我在malloc(-1)时,系统报错,分配的内存XXXX个字节失败,算了算分配的字节是4个G,为什么是4个G呢,转一个贴子,写的很好 。

每个进程会有4G的虚拟地址空间, malloc得到的的地址都是虚拟地址, 并且当malloc的时候, 操作系统并不会将实际的内存分配给进程的, 所以malloc只会占用进程自身的虚拟地址空间。

(1)char * p = (char *)malloc( 2G字节 ); =>申请失败.

(2)char * p = (char *)malloc( 1.9G字节 ); =>申请成功

(3)连续的申请10个300M的内存空间 for ( i=0; i前9次成功, 最后1次申请失败

(4)先申请1.9G, 再申请900M p = (char *)malloc( 1.9G字节 ); p = (char *)malloc( 900M字节 ); =>两次申请都成功. 

  32位的机器里, 一个进程的内存地址空间范围是0-3G共4个G, 其中最后一个G是内核态的地址空间, 所以给用户态的内存地址空间只留下了前3个G. 那么这样, malloc能够申请到3G以内的内存才对, 但是结果并非如此.

在(1)中我们申请2G的内存都没有申请到, 这是什么原因呢?

先让我们看一看实际上进程的4G内存空间都放着或被map着什么:

第0G和第1G:用户态地址空间

第2G:库函数映射等

第3G:内核态内存空间

用户态地址空间中还包含了进程代码本身占用的地址空间, 栈的空间等等.

第2G中, 库函数映射等只占用了很少的一部分空间,还有很多的空闲空间.

现在让我们解释这4个问题:

第(1)个问题, 由上图可以看出, 没有连续的2G的内存, 所以申请2G的连续内存是肯定失败的.

第(2), 申请1.9G的空间是成功的, 这是因为前两个G可能会有1.9G的连续空间.

第(3), 申请了300M*9 = 2.7G是成功的, 是的, 前3G中有可能空间着2.7G的空间, 前两个G中空闲的加上第3个G中空闲的部分. 但是如果一次申请2.7G是不行的, 因为没有连续的2.7G的地址空间.

最后一个300M没有申请成功的原因是, 申请的空间大小不能超过3G的用户态地址空间.

第(4), 比较有意思, 显然那个1.9G是在第1-2G这个地址空间中申请成功的, 后900M是第3个G这片地址空间中申请成功的. 我们一共申请到了2.8G的"内存", 却也不是连续的

本文来自 yazi0127 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/yazi0127/article/details/4235555?utm_source=copy

Logo

更多推荐