浅析动态内存分配栈与堆
来源:互联网 发布:java笔试多选题 编辑:程序博客网 时间:2024/05/17 03:21
先举个例子:某用户需要一个将任意多个整数按大小排序的程序。(在计算机文件夹中,当文件很多时经常用到排序)1。若不用动态分配内存,那就定义一个超大的数组吧!问题是,如果用户不需要那么大,不就浪费了?如果定义的数组还不够大,不就不能满足需求了?2。如果用动态分配,就解决上述问题了。当你需要多大内存时,就给你多大——如果有的话——这就是动态分配的意义。 现在看上述问题的代码,我调试过的:----------------------------------------------------------------------#include <stdio.h>#include <stdlib.h> void main(){ int n,*p,i,j,m; printf("本程序可对任意个整数排序;\n"); printf("请输入整数的总个数: "); scanf("%d",&n); p=(int *)calloc(n,sizeof(int)); if(p==0) { printf("分配失败!\n"); exit(1); } printf("请输入这些整数:\n"); for(i=0;i<n;i++) scanf("%d",p+i); for(i=1;i<n;i++) { for(j=0;j<n-i;j++) if(*(p+j)>*(p+j+1)) { m=*(p+j); *(p+j)=*(p+j+1); *(p+j+1)=m; } } printf("将这些整数从小到大排列输出为:"); for(i=0;i<n;i++) { if(i%5==0) printf("\n"); printf(" d;",*(p+i)); } printf("\n"); free(p); }---------------------------------------------------------------------- 调用calloc函数时,calloc(n,sizeof(int))表示请求n个连续的、每个长度为整型的空间,若成功返回这些空间的首地址。(int *)表示将这个地址放在指针中。到此为止,就可以用指针来对分配到的空间操作了。注意,最后一定要用free函数释放申请到的空间,否则这部分空间会一直占着。 malloc、calloc、realloc的用法(以上述问题为例)及区别: 1。malloc(n*sizeof(int)) 2。calloc(n,sizeof(int)) 3。realloc(p,sizeof(int)*n)
=====================================================================
一、概述:
二、内存分配方式
在操作系统中,内存分配主要以下面三种方式存在:
(2)栈上的内存分配。栈是系统数据结构,对于进程/线程是唯一的,它的分配与释放由操作系统来维护,不需要开发者来管理。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时,这些存储单元会被自动释放。栈内存分配运算内置于处理器的指令集中,效率很高,不同的操作系统对栈都有一定的限制。
(3) 堆上的内存分配,亦称动态内存分配。程序在运行的期间用malloc申请的内存,这部分内存由程序员自己负责管理,其生存期由开发者决定:在何时分配,分配多少,并在何时用free来释放该内存。这是唯一可以由开发者参与管理的内存。使用的好坏直接决定系统的性能和稳定。
三、动态内存分配概述
四、动态内存分配的实现
4.1、动态内存管理的一般机制:
4.2、Linux下动态内存分配的实现:
注意:这里我们讨论的都是虚拟内存的分配(即应用层面上的内存分配),主要由glibc来实现,它与内核中实际物理内存的分配是不同的层面,进程所分配到的虚拟内存可能没有对应的物理内存。如果所分配的虚拟内存没有对应的物理内存时,操作系统会利用缺页机制来为进程分配实际的物理内存。
4.3、Uc/OS 下内存分配的实现:
(1)、创建内存分区:在使用内存之前,开发者必须首先调用OSMemCreare()函数来创建相应的内存分区,在创建内存分区成功后,就会在系统中存在一个以开发者指定内存大小,指定内存块数目的内存池。在此过程中,开发者需要明确的知道系统的内存分布,并指明内存池的基址。
(2)、申请内存:当系统内存分区创建好了后,系统就可以从相应的内存分区中获取内存了。在Uc/OS 中,主要利用OSMemGet()来申请内存,应用程序会根据所需要内存的大小,从开发者指定的内存池中申请内存。
(3)、释放内存:因为内存是系统的紧缺资源,当应用不再需要使用所申请的内存时,应该及时释放该内存。在Uc/OS 中,主要利用OSMemPut()来释放不再需要的内存,在此过程中,开发者应该保证把该内存释放回原内存的分区。
五、小结:
在本文简单解析了两种动态内存管理实现,它们互有忧缺点:对于以虚拟内存机制和分页机制为基础的动态内存管理(如Linux等),由于请求分页机制的存在,不能满足系统实时性方面的要求,但是它能为应用提供最多能到4G的内存空间,而且由于应用虚拟内存机制,可以为进程空间提供保护,一个进程的崩溃不会影响其他的进程。对于基于非虚拟内存管理机制的系统,由于可以直接操作物理内存,提高了系统实时性,在这样的系统中,开发者的参与度比基于虚拟内存机制的要高。其缺点是没有进程间的保护机制,一个进程或任务的错误很容易导致整个系统的崩溃。
参考:
1、Glibc 源代码
2、嵌入式实时操作系统Uc/OS-II
3、经典收藏之 - C++内存管理详解:http://www.oneedu.cn/xxyd/jzjs/aspnet/200703/14963.html
4、Understanding Linux kernel
5、The Virtual-Memory Manager in Windows NT:
http://msdn2.microsoft.com/en-us/library/ms810616.aspx
============================================================================
堆是硬件实现的,栈是一种数据结构,但是很多情况已经不区分它们了
栈是由cpu实现的一种数据结构,其特点是后进先出。用于程序局部变量、程序返回地址。调用子程序、声明局部变量时,实际上就是在告诉编译程序使用“栈”这种数据结构。程序链接(link.exe)时,必须告诉链接程序为进程保留多大的栈空间。进程被加载时,操作系统就为该进程分配或者说保留这么大的内存空间作为栈来使用。
- 浅析动态内存分配栈与堆
- Java中的堆内存与栈内存分配浅析
- Java中堆内存与栈内存分配浅析
- Java中堆内存与栈内存分配浅析
- Java中堆内存与栈内存分配浅析
- Java中堆内存与栈内存分配浅析
- Java中堆内存与栈内存分配浅析
- Java中堆内存与栈内存分配浅析
- Java中的堆内存与栈内存分配浅析
- Java中堆内存与栈内存分配浅析
- Java中堆内存与栈内存分配浅析
- Java中的堆内存与栈内存分配浅析
- Java中堆内存与栈内存分配浅析
- Java中的堆内存与栈内存分配浅析
- Java中堆内存与栈内存分配浅析
- Linux_Java中堆内存与栈内存分配浅析
- Java中堆内存与栈内存分配浅析
- Java中的堆内存与栈内存分配浅析
- EBS Form开发 弹性域定义中的参数<三> .
- 然后对当前快照"关机",再重新启动快照的操作系统就可以了
- 语音验证码api 手机接听验证码
- 基于live555实现实时视频监控
- CSS过渡 && bootstrap transition
- 浅析动态内存分配栈与堆
- apache commons collections CollectionUtils工具类简单使用
- 索引的利弊与如何判定,是否需要索引
- WCDMA中RL失步是如何定义的?
- 如何高效的使用Xcode
- vlc的应用之六:简单的视频点播系统(B/S)的实现
- VxWorks信号、中断处理与定时机制
- KPN
- Deep Residual Learning for Image Recognition 笔记