关于C 语言的内存分配问题

      我们在做题时开数组经常会出现爆栈问题,那么这是为什么?

      让我们带着问题先来了解一下C语言的内存分区,C语言内存分为个区:

代码区:顾名思义这里是用来存储代码编译后的二进制机器码;

堆区:用于动态内存分配,一般由程序员分配或释放,如果程序员没有在程序运行中手动释放,那么会在程序结束后释放。

栈区:编译器自动分配和释放,一般用来存放局部变量、函数参数。

全局初始化数据区/静态数据区(Data Segment):用来存储全局变量和静态变量。

 ⑤未初始化数据区(BSS):在运行时改变值。改变值(初始化)的时候,会根据它是全局变量还是局部变量,进到他们该去的区。否则会持续待在BSS里面与世无争。(待会儿会用实验来证明并感受它的存在。)

       重点说一下栈区全局初始化数据区/静态数据区 我们常说的爆栈问题,大部分就是发生在了栈区,爆栈原因是我们定义了过大的数组栈区内存装不下了。那么我们把数组定义在了 main() 外面(也就是全局区)一般情况下不会爆栈,为什么?

      原因很简单 那就是在Windows下C语言分配给栈区的内存远小于全局区,全局区的内存与电脑的剩余内存有关,我们做题所定义的变量占用的内存简直就是小儿科,但是!!!分配给栈区的内存只有 2M(接近2M) !也就是说 。。。

先说一下计算机常用内存单位之间的换算 :

                                         1 M = 1024 KB ;1 KB = 1024Byte ; 1Byte = 8 bit

继续说:也就是说栈区只有 2 * 1024 *1024 = 2,097,152 字节  仅能储存 524,288 个int型变量(其实也不少了);但是在创建二维数组时要小心了 最大只能创建 int array[719][720] 的二维数组,否则 会爆栈;

那么为什么要把变量存储在栈区?直接储存在全局区多好?我们要这样想 它存在肯定有它存在的理由,经过查询:

      栈:由系统自动分配,速度较快。但程序员是无法控制的。

      堆:是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。

经过以上的探讨对C语言的内存分配有所了解了,再讲一个小知识点(BSS区):先看一段代码:

#include<stdio.h>
int main (){
	int array[518156]; 
	printf("sucess!\n");
	return 0;
} 

经过测试array[518156];这是我的电脑在栈区所能定义的最大整型数组(再增加一个都不行);

理论上说这时的栈区已经满了不能再增加变量了,再看下一段代码:

#include<stdio.h>
int main (){
	int array[518156];
	int test1,test2,test3,test4,test5,test6;

	double test7,test8,test9;

	float test10,test11,test12;

	char test13,test14,test15;

	printf("sucess!\n");
	return 0;
} 

      我在下面又定义了 6 个int 变量,3 个 double 变量,3 个 float 变量,3 个 char 变量 它还是没爆栈,为什么?

原因是 未赋值的 变量存储在了 BSS区 并未占用栈内存,当你 给任意个 变量(即使是最小的 char 变量) 赋了值 就会爆栈。

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值