作者:牛客192239号
链接:在1G内存的计算机中能否malloc(1.2G)?_技术交流_牛客网
来源:牛客网
问题:在 1G 内存的计算机中能否 malloc(1.2G) ?为什么?
【解答要点】:malloc能够申请的空间大小与物理内存的大小没有直接关系,仅与程序的虚拟地址空间相关。程序运行时,堆空间只是程序向操作系统申请划出来的一大块虚拟地址空间。应用程序通过malloc申请空间,得到的是在虚拟地址空间中的地址,之后程序运行所提供的物理内存是由操作系统完成的。
本题要申请空间的大小为 1.2G=2 30 × 1.2 Byte ,转换为十六进制约为 4CCC CCCC ,这个数值已经超过了 int 类型的表示范围,但还在 unsigned 的表示范围。幸运的是 malloc 函数要求的参数为 unsigned 。见下面的示例代码。
#include <stdio.h>
#include <stdlib.h>
int main()
{
char*p;
const unsigned k = 1024 * 1024 * 1024 * 1.2;
printf("%x\n", k);
p = (char *)malloc(k);
if (p != NULL)
printf("OK");
else
printf("error");
return 0;
}
调试结果:
4ccccccc
OK
【知识拓展】malloc能够申请的空间到底能达到多大,还真是一个比较复杂的问题。想知道在一台机器上malloc能够申请的最大空间到底是多少,可以使用下面的程序进行测试。
#include <stdio.h>
#include <stdlib.h>
unsigned maximum = 1024 * 1024 * 1024;
int main(int argc, char *argv[])
{
unsigned blocksize[] = { 1024 * 1024, 1024, 1 };
int i, count;
void* block;
for (i = 0; i < sizeof(blocksize) / sizeof(unsigned); i++){
for (count = 1; ; count++){
block = malloc(maximum + blocksize[i] * count);
if (block != NULL) {
maximum = maximum + blocksize[i] * count;
free(block);
}else {
break;
}
}
}
printf("maximum malloc size = %u bytes\n", maximum);
return 0;
}
注:本机环境为VS2017+Win10,运行内存8G。运行时间超过五分钟,仍未得出结果:
原文中提到:在当前正在使用的Windows环境中,可申请的最大空间超过1.9G。
实际上,具体的数值会受到操作系统版本、程序本身的大小、用到的动态/共享库数量、大小、程序栈数量、大小等的影响,甚至每次运行的结果都可能存在差异,因为有些操作系统使用了一种叫做随机地址分布的技术,使得进程的堆空间变小。感兴趣的读者可以去研究操作系统中的相关内容。
有了以上与malloc相关的知识后,对于下面问题的答案自然就容易理解了。
以下关于malloc及相关概念的说法中,错误的是( )。
A.内存泄露一般是指程序申请了一块内存,使用完后没有技术将这块内存释放,从而导致程序占用大量内存
B.无法通过malloc( size_t ) 函数调用申请超过该机器物理内存大小的内存块
C.无法通过内存释放函数 free( void * ) 直接将某块已经用完的物理内存直接还给操作系统
D.可以通过内存分配函数 malloc( size_t ) 直接申请物理内存
选项A和C的结论是正确的,选项B和D的概念是错误的。应用程序不能直接申请物理内存,malloc申请的是虚拟空间。