【操作系统】c++程序的内存分配

进程在 内存中的分区情况 是这样的:
1, 栈区(stack):栈区是由编译器自动分配和释放的,主要存放局部变量、函数参数值等,就连函数的调用过程都是用栈来完成的。
栈空间的大小是有限制的,一般是1~8Mb,跟操作系统有关,所以如果需要申请大块内存的时候栈空间往往是不够用的,需要借助堆(heap)内存来存储。
每一个线程都会有一个自己的栈空间。
栈区内存的生长方向是 从高到低的。
2, 堆区(heap):这个区域的内存空间是由程序猿管理的一段内存区域,由程序猿手动申请,同时使用完之后需要手动释放。如果程序猿没有释放,会造成内存泄漏,之后到程序结束的时候才由操作系统回收。
操作系统给每个进程允许使用的堆空间很大,几乎只收到真实物理内存大小的限制。
堆区空间的生长方向是 从低到高的,这一点与栈是不一样的,做个实验证实一下:
#include <iostream>
using namespace std;

int main()
{
 int a1 = 0, a2 = 0;
 int* p1 = new int(0);
 int* p2 = new int(0);

 cout<<&a1<<" "<<&a2<<endl;
 cout<<p1<<" "<<p2<<endl;

 return 0;
}


看结果,a2地址要低于a1地址,而对于堆,p2 > p1。

3, 全局区(静态区)(static):全局变量和静态变量的存数区域,未初始化的全局变量和未初始化的静态变量放在一块区域,初始化过的放在相邻的一块区域。这段内存区域在编译时就申请好了,程序结束后由系统释放。
4, 文字常量区:主要存放常量字符串,程序结束之后由系统释放空间,因为存储的是常量,所以这个区域的内存是不能够被修改的。
5, 程序的代码区:这个区域主要存放程序的二进制代码。

栈和堆的区别:
主要区别由以下几点:
  1、管理方式不同;
  2、空间大小不同;
  3、能否产生碎片不同;
  4、生长方向不同;
  5、分配方式不同;
  6、分配效率不同;
  管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。
  空间大小:一般来讲在32位系统下,堆内存可以达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有一定的空间大小的,例如,在VC6下面,默认的栈空间大小是1M。当然,这个值可以修改。
  碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出,在他弹出之前,在他上面的后进的栈内容已经被弹出,详细的可以参考数据结构。
  生长方向:对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。
  分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由malloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。
  分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分 到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
  从这里我们可以看到,堆和栈相比,由于大量new/delete的使用,容易造成大量的内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和核心态的切换,内存的申请,代价变得更加昂贵。所以栈在程序中是应用最广泛的,就算是函数的调用也利用栈去完成,函数调用过程中的参数,返回地址, EBP和局部变量都采用栈的方式存放。所以,我们推荐大家尽量用栈,而不是用堆。
  虽然栈有如此众多的好处,但是由于和堆相比不是那么灵活,有时候分配大量的内存空间,还是用堆好一些。
  无论是堆还是栈,都要防止越界现象的发生(除非你是故意使其越界),因为越界的结果要么是程序崩溃,要么是摧毁程序的堆、栈结构,产生以想不到的结果。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
操作系统内存分配算法是操作系统中的一种重要的组成部分,它负责管理和分配计算机的内存资源,以优化内存的利用和提高系统的性能。 其中,C语言是一种高级编程语言,常用于系统开发和应用程序编程。在操作系统内存分配算法中,C语言可以用来实现算法的具体逻辑。 内存分配算法可分为静态分配和动态分配两种。静态分配是指在程序编译时,将所需的内存分配程序。这种分配方式简单、高效,适用于内存需求固定的情况,但灵活性较差。动态分配是指在程序运行时根据需要动态地分配和释放内存。C语言中的内存分配函数malloc()和free()可以用来实现动态分配内存的功能。 常用的内存分配算法有首次适应算法、最佳适应算法和最坏适应算法等。首次适应算法是指在内存块中找到第一个能满足分配要求的块进行分配。最佳适应算法是指在内存块中找到能满足分配要求且剩余空间最小的块进行分配。最坏适应算法是指在内存块中找到能满足分配要求且剩余空间最大的块进行分配。 内存分配算法的选择应根据系统的需求和资源情况来确定。不同的算法有不同的优缺点,如首次适应算法简单、执行效率高,但容易产生内存碎片;而最佳适应算法能更加合理地分配内存,但需要更多的时间和计算资源。 总之,操作系统内存分配算法可以通过C语言实现,常用的算法有静态分配和动态分配,以及首次适应、最佳适应和最坏适应等。选取适当的算法可以提高内存的利用率和系统的性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ango_Cango

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值