说白了,内存的静态分配和动态分配的区别主要是两个:
一是时间不同。静态分配发生在程序编译和连接的时候。动态分配则发生在程序调入和执行的时候。
二是空间不同。堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由函数malloc进行分配。不过栈的动态分配和堆不同,他的动态分配是由编译器进行释放,无需我们手工实现。
对于一个进程的内存空间而言,可以在逻辑上分成3个部份:代码区,静态数据区和动态数据区。动态数据区一般就是“堆栈”。“栈(stack)”和“堆(heap)”是两种不同的动态数据区,栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”,所以每个线程虽然代码一样,但本地变量的数据都是互不干扰。一个堆栈可以通过“基地址”和“栈顶”地址来描述。全局变量和静态变量分配在静态数据区,本地变量分配在动态数据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。
一般,用static修饰的变量,全局变量位于静态数据区。函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。
首先,在使用动态分配内存技术前,必须明白自己在做什么,这样做与其它的方法有什么不同,特别是会产生哪些负面影响,天下没有免费的午餐。动态分配内存与静态分配内存的区别:
1) 静态内存分配是在编译时完成的,不需要占用CPU资源;动态分配内存是在运行时完成的,动态内存的分配与释放需要占用CPU资源;
2) 静态内存分配是在栈上分配的,动态内存是堆上分配的;
3) 动态内存分配需要指针或引用数据类型的支持,而静态内存分配不需要;
4) 静态分配内存需要在编译前确定内存块的大小,而动态分配内存不需要编译前确定内存大小,根据运行时环境确定需要的内存块大小,按照需要分配内存即可。可以这么说,静态内存分配是按计划分配,而动态内存分配是按需分配。
5) 静态分配内存是把内存的控制权交给了编译器,而动态内存是把内存的控制权交给了程序员;
综上所述,静态分配内存适合于编译时就已经可以确定需要占用内存多少的情况,而在编译时不能确定内存需求量时可使用动态分配内存;但静态分配内存的运行效率要比动态分配内存的效率要高,因为动态内存分配与释放需要额外的开销;动态内存管理水平严重依赖于程序员的水平,如果处理不当容易造成内存泄漏。那么再具体些,如何选择内存分配方式,如果动态分配内存需要注意哪些问题呢?
需要强调的是,由于动态分配内存把内存的控制权交给了程序员,程序员有义务写代码确认内存分配成功能,如果分配失败要做适当处理,否则将给你的程序进而下一个定时炸,随时有可能因为动态内存分配失败而导致程序崩溃。
1. 全局变量尽可能不要动态分配内存。
既然将变量定义为全局变量,就为了其可见范围比较宽,因为可能这些变量在整个程序的运行期都是可见的,可能根本就没有机会释放全局变量所占用的内存,所以使用动态分配内存是意义不大的,只能给程序带来额外的运行负担。
但对于全局变量内存大小不能确定的情况,可能会有例外。比如要处理一批数据,数据的大小可能由用户通过控制台参数形式告诉程序,这种情况可以动态按需分配内存,合理使用内存。
而对于编译时能够确定内存使用量的全局变量,而且变量工作期(暂且这么叫吧,就是该变量还可能会被用到的这段时期)又与程序的运行期相同的情况根本没有必要动态分配内存。这种情况很有意思,就是使用动态分配内存,但可以不考虑释放这块内存,因为可以释放内存的时候该程序也要退出了,程序一结束,进程也就结束了,整个程序所在的虚拟空间已经被全部释放,也就没必要去添加释放内存的代码了。(但我确定见到过这样的代码)
2. 动态分配内存时,分配与释放的代码要对称。
这里说的分配与释放的代码对称指,分配内存的代码要与释放内存的代码在同一个范围的代码域中,例如在一个函数的开头申请内存,就应该在这个函数的结尾释放内存,否则,如果在一个函数内部分配内存,在函数外释放内存,就有可能因程序员的疏忽造成内存泄漏;如果内存分配在某个类的构造函数中,那么就应该在析构函数中释放内存,千不要在另外一个函数中释放,而等着客户代码去掉用那个函数去手动释放内存,如果那样的话就相当于埋了一个定时炸,随时可能因为一时的疏忽而造成内存泄漏。
3. 对动态创建的对象或分配的内存块一定要检查期有效性。
由于操作系统的并发性和复杂性,任何一次动态内存的分配操作都有可能失败,特别是申请一次较大块内存时。所以一定要检查动态创建的对象或申请的堆内存是否成功,否则可能因为错误的指针或空指针造成程序异常,如果异常没有得到适当处理的话,可能使整个程序意外终止,造成损失。
4. 尽可能少次数地使用动态内存分配。
动态分配是在运行时由操作系统完成的,所以是要消耗CPU资源的,在进行动态内存分配时尽可能便利已经分配的资源。如果上次申请的资源够用就不要重新申请资源,不够用时才释放旧资源,申请新资源。
5. 在保证资源利用率的前提下,能用静态内存分配不用动态分配,特别是局部临时对象。
例如,对于局部对象,使用静态分配的内存,可以由编译器编译时分配,超出作用域自动内存,不仅减小了程序代码,减少了错误产生的概率,减轻了程序员的负担,而且提高的程序的执行效率,何乐而不为呢?
转载于江苏三艾网络
分享到:
相关推荐
静态分配主要用于批处理系统,它在程序编译时或加载到内存时就确定了内存空间,这种分配方式对于某些类型的应用程序,特别是那些大小固定、运行时间较长且不需频繁动态扩展的程序来说,是十分合适的。 静态内存分配...
- 动态内存分配和静态内存分配之间存在区别,静态内存分配在栈上进行,由编译器分配和系统自动释放;动态内存分配在堆上进行,由程序员自行管理内存的申请和释放。 在实际的软件开发中,正确使用动态内存分配能够...
3. 查看已分配内存:为了监控内存分配情况,程序需要提供查看当前内存分配状态的功能。这可以通过遍历作业链表并打印相关信息来实现。 4. 内存回收:当不再需要某段内存时,必须将其归还给系统,以便后续分配。回收...
在Linux操作系统中,设备驱动程序通常使用kmalloc或kmem_cache等函数来动态分配内存。然而,有时设备驱动可能需要静态分配物理内存,即在特定的物理地址进行内存分配,以便满足某些硬件的要求或者提高效率。Linux...
服务器使用两种主要的内存分配策略:动态分配和静态分配。理解这两种方法如何工作可以帮助管理员更好地调整SQL Server以适应不同的环境需求。 动态内存分配是SQL Server的默认设置,允许系统根据实际需要自动调整...
在传统的操作系统中,内存分配通常分为静态分配和动态分配两种方式。 1. 静态分配:在程序编译时就确定了内存需求,分配的内存区域在整个程序执行过程中保持不变。这种方式简单且效率高,但缺乏灵活性,难以适应...
堆是程序运行时动态分配内存的空间,它不受函数调用的限制,可以被多个函数共享。堆内存的分配和释放由程序员通过调用特定的库函数或API来控制,如在C/C++中使用`malloc()`、`calloc()`、`realloc()`和`free()`函数...
与静态内存分配不同,它不需要在编译时确定内存需求,而是根据运行时的实际需求动态调整。这种灵活性使得动态内存分配成为现代编程语言中不可或缺的一部分。 ### 二、动态内存分配的实现 #### 2.1 内存模型 在...
动态内存分配是指在程序运行时根据需要分配内存的方式。这种方式通过标准库函数`malloc`、`calloc`、`realloc`和`free`来实现。 - **运行时分配**:内存在程序运行时根据需要动态分配。 - **作用域不受限**:动态...
1. **静态内存分配**:在程序开始执行时,操作系统为全局变量和静态变量分配内存。这部分内存存在于数据段和BSS段。BSS段存储未初始化的全局和静态变量,而数据段则存储已初始化的变量。 2. **动态内存分配**:在...
动态内存分配与静态内存分配不同,后者在编译时就已经确定了内存空间的大小和位置。 堆内存分配是动态内存分配的主要方式。在C++中,`new`运算符用于在堆上分配内存,而`delete`运算符用于释放内存。当使用`new`...
在编程领域,动态分配内存是一种重要的技术,它允许程序在运行时根据需要分配或释放内存。这种方法对于实现灵活的数据结构,如数组,特别是在资源有限的嵌入式系统中,是至关重要的。本主题将深入探讨动态内存分配...
动态内存分配是程序在运行时根据需要请求系统分配内存的过程,与静态内存分配(编译时确定大小)相对。"DynMem.rar"这个压缩包文件显然包含了关于动态内存分配的实践示例,特别是针对最优算法(Best Fit)和最先算法...
利用malloc和 calloc函数实现动态内存的分配;利用free函数实现动态内存...1、 了解静态内存与动态内存的区别; 2、 理解动态内存的分配和释放原理; 3、 掌握如何调整动态内存的大小; 4、 利用链表实现动态内存分配。
主要的内存分配方法包括静态分配和动态分配。静态分配通常在程序加载时完成,而动态分配则在程序运行时根据需要进行。 1. 静态内存分配:这种方法通常用于早期的操作系统,它在编译时就确定了程序所需的内存大小。...
静态内存分配是其中一种常见的内存管理策略,与动态内存分配相对。本篇将深入探讨静态内存分配的概念、原理以及在Nordic平台上的应用。 静态内存分配是指在程序编译时或运行前就已经确定了内存块的大小和位置。这种...
1. **malloc() 函数**:这是C语言中用于动态分配内存的主要函数,它接受一个整型参数,表示所需的字节数,如果成功,返回一个指向分配内存的指针。例如,`ptr = (类型*) malloc(size);` 分配了`size`字节的内存,并...
### C和C++中的动态内存分配详解:堆、栈、数据段 #### 一、C语言中的内存区域 在C语言中,程序运行时的内存主要分为以下几个区域: 1. **栈区**:由编译器自动分配和释放。主要用于存放函数调用时的局部变量、...
本资源讲解了链表的基本概念和实现方式,着重介绍了静态链表和动态链表的区别和应用场景。链表是一种常见的数据结构,它由多个节点组成,每个节点都包含一个数据域和一个指向下一个节点的指针。链表的优点是可以动态...