C++面试题(21)| malloc最大申请数

949 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情

image.png

(欢迎大家关注我的微信公众号——控制工程研习,上面会分享很多我学习过程中总结的笔记。)

本题来自深信服C++面试

答案

    如果不考虑其他的情况,在 Linux 上(对于其他 POSIX 系统也是如此),malloc() 的可分配大小size_t,最高可达 SIZE_MAX,在 32 位系统上为可以达到2^32字节,在 64 位系统上,可以达到2^64 字节。

    但是,malloc是libc的一个函数,并不是系统调用。因此并不是内存空间的终极管理者。最大能够申请多大空间,并不是malloc这个函数能说了算的。

限制因素:

1. 操作系统(处理内存的方式不同)

    操作系统的地址空间分布决定了用户可用的最大地址空间,比如32位Windows是用户2G+内核2G的地址空间分配方式,32位Linux是用户3G+内核1G,不同操作系统的实现方式,对malloc也是有影响的。

2. 硬件

    32位和64位的硬件限制是不一样的,页表的支持情况(巨型页)也会对malloc有限制。把范围扩大的话,对于不同的硬件架构(ARM/PPC/MIPS),页表和地址空间的限制也都不完全一致。

3. 当前内存的使用状况:

    地址空间限制是有的,但是malloc通常情况下申请到的空间达不到地址空间上限。内存碎片会影响到你 “一次” 申请到的最大内存空间。比如你有10M空间,申请两次2M,一次1M,一次5M没有问题。但如果你申请两次2M,一次4M,一次1M,释放4M,那么剩下的空间虽然够5M,但是由于已经不是连续的内存区域,malloc也会失败。系统也会限制你的程序使用malloc申请到的最大内存。

    windows下32位程序如果单纯看地址空间能有4G左右的内存可用,不过实际上系统会把其中2G的地址留给内核使用,所以你的程序最大能用2G的内存。除去其他开销,你能用malloc申请到的内存只有1.9G左右。

函数介绍

    malloc的全称是memory allocation,中文叫动态内存分配,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存。

    void* 类型表示未确定类型的指针。C/C++规定,void* 类型可以通过类型转换强制转换为任何其它类型的指针。 

    malloc一般需和free函数配对使用。 

    基本用法:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
int main()
{
   char *str;
 
   /* 最初的内存分配 */
   str = (char *) malloc(15);
   strcpy(str, "runoob");
   printf("String = %s,  Address = %u\n", str, str);
 
   /* 重新分配内存 */
   str = (char *) realloc(str, 25);
   strcat(str, ".com");
   printf("String = %s,  Address = %u\n", str, str);
 
   free(str);
 
   return(0);
}