(.bss段和静态变量 malloc和free)C语言之内存分配

以前学习C语言时没有过多地深入到底层,导致对许多的原理、机制理解得不够透彻,内存分配就是其中之一,恰巧今天看了有关内存分配的知识就写篇博文来记录一下,毕竟好记性不如烂笔头嘛。
我想很多同学对C语言中的堆、栈这些概念都似懂非懂,我在网上找了一篇很好的博文大家可以参考一下,链接如下(https://blog.csdn.net/youoran/article/details/10990815)。
(以下部分内容转自链接博文)
C程序的存储结构在运行时和存储时是不同的,如下图所示:
在这里插入图片描述
左边是程序未执行时的存储结构,右边是运行时的存储结构。

非运行时(即存储时)编译后的C程序有两个“区”——代码区和静态数据区。代码区就是存放的程序编译后的指令;静态数据区存放的是一些全局变量、静态变量等,静态数据区根据有没有初始化分成两类,BSS区就是指未初始化的区域(其实bss段在非运行时是不分配内存的,只是在段表里记录该段的大小,在符号表记录该段的符号,等真正运行时才会给它分配空间并全部初始化为0,所以有人说“bss段不占用磁盘空间”,有兴趣的同学可以参考(https://blog.csdn.net/move_now/article/details/69307890))。
例子:

int a[100];
int b[100]={0};
int main()
{
	static int c;
	static int d=1;
	...
	return 0;
}

这里a、c就是存放在bss数据段,只有程序运行时才去给它分配空间并初始化(即自动清0);b、d都是存放在静态数据段的并且在已经进行了初始化操作。这也是为什么有人说静态变量若未初始化,就会被程序自动初始化为0,因为它被放在了bss段。

运行时的存储结构较运行前多了“堆”和“栈”两个区域,有关堆和栈的异同之处网上博客很多,这也是面试时HR特别喜欢问的东西,我这里不去展开(第一个链接里有一定程度地展开)。这里要注意一下图中堆和栈增长方向提示,在不同的机器中可能是不同的,不能一概而论。

分割线—————————————————————————————————————
当我们使用malloc、calloc等请求动态分配内存的函数时,操作系统就会在堆中给我们分配一块内存,当我们使用完毕时需要手动地去释放这块内存,不然这块内存就一直会被占用但又没有被实际使用,就会引起“内存泄漏”。
“堆”有可能会发生内存泄漏,但“栈”是由系统自己去维护的,不会发生内存泄漏的问题

既然有可能发生内存泄漏,那么为什么要引入动态分配内存?
因为在实际操作过程中,你很难确定究竟要使用多少内存。
比如你要统计学校里每个学院的人数,假设每个学院的人数不超过1000人,那么你可以声明一个a[1000]来存储信息,但如果有个学院只有100人呢?那剩下的900个内存单位不就浪费了?或者说今年某个学院扩招了,人数突破1000了,那你原先的a[1000]还能使用吗?
使用动态分配就可以很好地解决这些问题,你多一个人我就多分配一次,既不会浪费内存也不会产生溢出。

动态分配内存的函数有malloc、calloc、realloc,它们的原型如下:
void *malloc(size_t size);
void *calloc(size_t num_elements, size_t element_size);
void realloc(void *ptr,size_t new_size);
malloc的入口参数是请求内存大小的字节数;
calloc的入口参数1是请求的内存单位数量,参数二是请求的内存单位的大小,比如
int * a = (int *)calloc(100,sizeof(int));请求分配了100个int单位,如果你的机器上int是4字节的,那就是请求了400个字节的大小。calloc还有一点与malloc不同,就是calloc请求分配的内存会被初始化为0。
realloc用于修改一个原先已经分配的内存块的大小。
这三个函数都可以用free来释放申请的内存(一定要记得free!!!)。
若在申请内存时返回的指针为NULL则表示分配不成功。

待续。。。。。。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值