C语言可以分配的最大内存
前言
最近用C刷PAT算法题目, 发现C语言有太多需要关注大小范围的东西必须
知道, 虽说挺麻烦, 但也挺有意思.
int最大值是多少
首先就是int类型的取值范围, 这个太常用. C语言标准规定最低范围是
[-2^16 + 1, 2^16], 即[-65535, 65536], 但这个明显已经过时, 目前
绝大部分机器支持的int范围是[-2^32 + 1, 2^32], 也就是正负20个亿
左右, 因此大家刷题的时候只要整数范围是在20亿这个量级, 就可以大胆的
使用int, 不必动用long int, long long int等. 更多关于C语言
自带数据类型极限, 以及在自己本地测试数据类型极限, 可以访问
这里
1000万的整型数组能不能运行
如果我们直接在C程序main函数中开个1000万的整型数组, 运行这个程序会发生
什么 ?
#include <stdio.h>
int main() {
int arr[10000000]; // 1000万
arr[400] = 123;
printf("%d\n", arr[400]);
return 0;
}
在win10_64位 CodeBlock 16.01下运行结果:

在win10_64位 gcc6.3.0(MinGW)命令行编译运行结果:

可以看到, 在IDE中运行程序直接崩溃, 在命令行中什么也没输出,
总之就是程序运行不正常, 可以理解为内存爆掉了. 难道C语言连
1000万的整型数组都开不出来吗?
举个例子:若果大家经常刷算法题应该有这个经验很多时候用一个
非常大的数组解题会显著提高效率, 非常方便. 比如输入100万
个数, 每个数都不大于10万, 然后任意给你一个数, 问你这个数存
不存在, 也就是查找, 若果按照传统的方法就算用C语言自带的2分
查找法, 每次在100万个数据中找出一个数, 工作量依旧非常巨大,
而且效率低下, 而直接把输入的数据当数组下标开个10万的数组解决,
问题则非常简单. 说到这里相信懂的人已经懂了, 如果不知所云也没
关系, 继续刷题, 以后回过头来看.
当我们谈C语言内存的时候我们再谈什么
大家可能都能听过什么栈内存, 堆内存, 什么堆栈, 静态内存, 动态内存
等等, 一些概念, 乍一看一脸懵逼, 这些都什么玩意, 我们现在先不关注
概念的东西, 直接看实际需求.
上面我们已经提到, 在main函数中开个1000万的整型, 程序就爆掉了, 那
到底, 最大能开多大的容量的整型数组, 才能不爆掉呢. 首先我们先来一波
计算, 大部分机器sizeof(int)得到的值是4, 也就是一个整型数据
需要4个字节的容量, 1000万个整型数组需要4 * 10000000 / 1024 / 1024,
计算结果大约是38M
1G = 1024M, 1M = 1024K, 1K = 1024byte(字节)
在Linux或者是在windows下的mingw环境下, 可以输入命令ulimit -a, 查看
C语言内存分配情况, 在下图我的机器上可以看到stack size大约为2M

按照一个整型数据占4个字节来算, 2M内存用来开数组, 最大也就开个52万左右,
我们的测试开了1000万, 显然是要爆掉的. 那么问题来了, 难道我们的C语言,
就TM只能提供区区50来万的数组空间吗? 别说50万, 就是1千万, 也不一定完全
够用呀. 当然不是, 上面只是C语言分配内存的默认方法, 也是最简单的方法,
这种方法用的是栈内存, 而C语言能提供的栈内存非常有限, 顶天就那么几M,
如果需要拿到更大的内存空间, 就不能使用这种方法了.
若果大家觉得52万, 貌似已经够自己用了, 我只能说, 兄弟再刷两题看看
栈和堆栈意思一样, 堆是另一种数据结构
我就是需要需要很大的内存空间怎么办
第1种方法: 使用malloc
这种方法我在这里不展开细说了, 如果大家对malloc很熟的话, 我这么
一提大家应该就明白了. 最简单的用法就是用malloc分配数组空间
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr;
arr = (int*)malloc(10000000 * sizeof(int));
arr[400] = 200;
printf("%d\n", arr[400]); // 正常输出 200
free(arr);
return 0;
}
第2种方法: 把变量声明放到文件作用域中(或者叫全局作用域)
这种方法重点推荐使用, 简单粗暴非常方便, 什么叫文件作用域就是把
变量声明挪到所有函数之外, 也就是main函数的上面即可. 源代码几乎
不用作任何改动, 直接把大数据变量声明搬到main函数上面即可.
#include <stdio.h>
#define LEN 24
long long int arr[1 << LEN]; // 声明放到这里就对啦
int main() {
for (long long int i = 0; i < (1 << LEN); i++) {
arr[i] = i + 200;
printf("i: %d\n", i);
}
return 0;
}
1 << 24相当于1000000000000000000000000(24个0), 也就是2^24 = 16777216
下面是我机器的运行结果, 注意运行时间可能会非常长

可以看到, 即便是开出1600万, 这么大的数组, 程序依旧能够正常运行.
总结
C语言的内存分配模式大致分为3种
- 自动分配. 也就是写在main函数或其它函数里面的, 使用的是栈内存,
一般栈内存只有几M, 所以这种方法, 分配的整型数组空间可能只有
几十万, 一般建议刷算法题的时候, 超过10万就不用这种方法 - 使用malloc分配, 可以分配的很大, 一般是几个G
- 把声明放在全局作用域中, 可以分配的很大, 一般是几个G
参考
warning: left shift count >= width of type
C Primee Plus 第6版 中文版 2016.4出版 Stephen Prata著 姜佑译
C语言可以分配的最大内存的更多相关文章
- 《C语言中分配了动态内存后一定要释放吗?》
问:比如main函数里有一句 malloc(),后面没有free()1.那么当main结束后,动态分配的内存不会随之释放吗?2.如果程序结束能自动释放,那么还加上free(),是出于什么考虑? 答: ...
- 【ZZ】C 语言中的指针和内存泄漏 & 编写高效的C程序与C代码优化
C 语言中的指针和内存泄漏 http://www.ibm.com/developerworks/cn/aix/library/au-toughgame/ 本文讨论了几种在使用动态内存分配时可以避免的陷 ...
- c语言类型修饰符及内存
今天来学习一下c语言类型修饰符及内存分布 1.auto int a; 默认在内存 2.register int a; 限制变量定义在寄存器上的修饰符 编译器会尽量安排CPU的寄存器去存放这个a,如果寄 ...
- (转)java内存分配分析/栈内存、堆内存
转自(http://blog.csdn.net/qh_java/article/details/9084091) java内存分配分析/栈内存.堆内存 java内存分配分析 本文将由浅入深详细介绍Ja ...
- C语言笔记 12_可变参数&内存管理&命令行参数
可变参数 有时,您可能会碰到这样的情况,您希望函数带有可变数量的参数,而不是预定义数量的参数.C 语言为这种情况提供了一个解决方案,它允许您定义一个函数,能根据具体的需求接受可变数量的参数.下面的实例 ...
- C语言中储存类别和内存管理
C语言中储存类别和内存管理 储存类别 C语言提供了多种储存类别供我们使用,并且对应的有对应的内存管理策略,在了解C中的储存类型前,我们先了解一下与储存类型相关的一些概念. 1. 基础概念 对象:不同于 ...
- SQL SERVER 内存分配及常见内存问题 简介
一.问题: 1.SQL Server 所占用内存数量从启动以后就不断地增加: 首先,作为成熟的产品,内存溢出的机会微乎其微.对此要了解SQL SERVER与windows是如何协调.共享内存.并且SQ ...
- 怎样给WordPress分配更多的内存
WordPress如果内存不够,你在操作的时候,就会碰到像这样的问题”Allowed memory size of xxxxxx bytes exhausted”(允许的内存 xxxx 字节已经用光了 ...
- C语言中计算变量占用内存空间
C语言中计算变量占用内存空间 在C语言中通常用[sizeof]运算符计算变量占内存空间,如下面的例子:
随机推荐
- 使用GitHub建立个人网站
使用GitHub建立个人网站 1 Git简介 2 为什么使用Github Pages 3 创建Github Pages 3.1 安装git工具. 3.2 两种pages模式 3.3 创建步骤 3.4 ...
- jquery mobile小经验
现在网站上关于jquery mobile的demo和帖子可真少啊,我刚开始接触,遇到了一些问题,都找不到人请教. 这是我的个人经验总结,或多或少会对刚入门的童鞋有点帮助吧. 如果想一开始进入页面的时候 ...
- Differential Geometry之第六章平面曲线的整体性质
第六章.平面曲线的整体性质 1.平面的闭曲线 1.1.切线的旋转指数定理 1.2.等周不等式与圆的几何特性 ,其中 2.平面的凸曲线 支撑函数: 2.1.Minkowski问题 2.2.四顶点定理
- GAN 生成mnist数据
参考资料 GAN原理学习笔记 生成式对抗网络GAN汇总 GAN的理解与TensorFlow的实现 TensorFlow小试牛刀(2):GAN生成手写数字 参考代码之一 #coding=utf-8 #h ...
- IIS故障问题(Connections_Refused)分析及处理【转】
这篇文章其实已经写好很久,只是后来一直没有重现当时的问题,或者因为业务的重要性.投诉的压力也就临时处理了.这几天某地市Web服务器连续多次出现这个问题,正好借这个案例来做个收尾. 前几个月有台重要的W ...
- ssh证书登录(实例详解)
前言 本文基于实际Linux管理工作,实例讲解工作中使用ssh证书登录的实际流程,讲解ssh证书登录的配置原理,基于配置原理,解决实际工作中,windows下使用SecureCRT证书登录的各种问 ...
- ASP.NET MVC 随想录
http://www.cnblogs.com/OceanEyes/category/696137.html
- 分页技巧_测试并继续改进分页用的QueryHelper辅助对象
分页技巧_测试并继续改进分页用的QueryHelper辅助对象 QueryHelper.java /** * 用于辅助拼接HQL语句 */ public class QueryHelper { pri ...
- 剑指 offer set 24 扑克牌的顺子
题目 从扑克牌中任意抽取出 5 张牌, 判断是不是顺子, 并且大小王可以看成任意的数字 思路 1. 把大小王当做 0 插入到数组中, 然后对数组排序 2. 统计相邻两个数之间的空隙数, 若空隙数大于 ...
- Android之ListView中的分割线
ListView中每个Item项之间都有分割线,设置android:footerDividersEnabled表示是否显示分割线,此属性默认为true. 1.不显示分割线只要在ListView控件中添 ...