`
trix
  • 浏览: 84869 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

c/c++ 内存管理

阅读更多
一、预备知识—程序的内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放
4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。

二、例子程序
这是一个前辈写的,非常详细

//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b;// 栈
char s[] = "abc"; //栈
char *p2; //栈
char *p3 = "123456"; 123456\0";//在常量区,p3在栈上。
static int c =0; //全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
//分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。


三、堆和栈的理论知识
3.1申请方式
stack:
由系统自动分配。 例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间
heap:
需要程序员自己申请,并指明大小,在c中malloc函数
如p1 = (char *)malloc(10);
在C++中用new运算符
如p2 = (char *)malloc(10);
但是注意p1、p2本身是在栈中的。
3.2 申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,
会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
3.3申请大小的限制
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
3.4申请效率的比较:
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活
3.5堆和栈中的存储内容
栈: 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。
3.6存取效率的比较

char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
#include <stdio.h>;
void main()
{
char a = 1;
char c[] = "1234567890";
char *p ="1234567890";
a = c[1];
a = p[1];
return;
}
对应的汇编代码
10: a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。


3.7小结:
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

堆和栈的区别主要分:
操作系统方面的堆和栈,如上面说的那些,不多说了。
还有就是数据结构方面的堆和栈,这些都是不同的概念。这里的堆实际上指的就是(满足堆性质的)优先队列的一种数据结构,第1个元素有最高的优先权;栈实际上就是满足先进后出的性质的数学或数据结构。
虽然堆栈,堆栈的说法是连起来叫,但是他们还是有很大区别的,连着叫只是由于历史的原因。
分享到:
评论

相关推荐

    C/C++内存管理深入详解

    C/C++内存管理是编程领域内极具挑战性的主题之一,它涉及到了内存分配、使用和回收的复杂机制。作为开发者,必须理解内存管理的各个方面,否则可能造成内存泄漏等严重问题,这些问题将导致程序不稳定甚至崩溃。本...

    MIT开放课程源码及资料_C/C++内存管理

    在MIT的开放课程中,C/C++内存管理是编程学习中的一个重要部分,它涉及到程序运行时如何有效地分配、使用和释放内存。C++作为一种强类型、静态类型的编程语言,其内存管理相较于高级语言如Java或Python更为底层和...

    深入C/C++内存管理:手动控制内存的艺术

    本文通过介绍C/C++中的内存管理方法和最佳实践,希望能够帮助读者掌握手动内存管理的技巧,避免常见的内存错误。 本文详细介绍了在C/C++中手动管理内存的方法,包括内存分配与释放、避免内存错误以及智能指针的使用...

    C/C++内存管理机制

    在C/C++编程中,内存管理是至关重要的,因为它直接影响程序的性能和稳定性。与一些高级语言不同,C/C++不提供自动的垃圾回收机制,程序员需要手动管理内存的分配和释放。本篇文章将深入探讨C/C++的内存管理机制,...

    C/C++内存管理之堆栈管理法

    C/C++语言中,程序员可以直接管理内存(指针),极大地方便了开发,增强了C/C++语言的灵活性。与此同时,直接管理内存也带了不可估量的后患,如果管理不好,内存问题一堆一堆出现,最常见的是内存非法访问、内存泄漏...

    C/C++内存管理-内存分配

    详细讲解C++内存分配的问题及C++与C分配内存的方式的不同,同时介绍在C++中分配内存的最佳方式。

    c/c++中文帮助文档(API)

    C库函数主要包括I/O操作、内存管理、字符串处理、数学运算、时间日期处理等。例如,`stdio.h`提供了基本的输入/输出操作,如`printf`用于格式化输出,`scanf`用于从标准输入读取数据;`stdlib.h`包含了内存分配和...

    从缺陷中学习C/c++

    在C/C++编程中,程序员经常会遇到各种陷阱,这些陷阱往往源于语言的特性和复杂性,例如指针管理不当、数组越界、内存泄漏、资源释放错误等。这些缺陷不仅可能导致程序崩溃或行为异常,还可能引入安全漏洞。 ### ...

    c/c++实现,内存管理,操作系统课程设计源程序

    5. **C/C++内存管理**:在C/C++编程中,内存管理主要依赖于`malloc()`、`calloc()`、`realloc()`和`free()`等函数。`malloc()`动态分配指定大小的内存,`calloc()`分配并初始化内存,`realloc()`改变已分配内存的...

    C_C++ 内存管理算法和实现 Memory Management Algorithms and Implementation in C_C++

    C_C++ 内存管理算法和实现 Memory Management Algorithms and Implementation in C_C++ &lt;br/&gt;C_C++ 内存管理算法和实现 Memory Management Algorithms and Implementation in C_C++ &lt;br/&gt;C_C++ 内存管理算法和实现 ...

    C/C++内存管理类本科毕设论文(ppt+论文)(绝对真实~)

    本文首先总结了C和C++中动态内存分配函数的使用要点,然后总结并分析了 C+ + 中常见的内存错误,提出了一些解决对策和预防措施 ,最后通过加入检测区域、重载new操作符来完成C++程序中部分内存越界问题的检测。

    C/C++ 标准库函数 (中文版)

    标准库中包含了输入输出处理、字符串操作、数学计算、时间日期处理、内存管理等函数,此外C++标准模板库(STL)提供了更高级的数据结构和算法实现。 首先,让我们来了解预处理命令。预处理是C/C++编译过程的一个...

    C/C++ API 帮助文档大全(中文,chm格式)

    8. **内存管理**:C++提供了手动内存管理,如new和delete操作符,但也需要开发者注意内存泄漏和悬挂指针的问题。C++11引入了智能指针(shared_ptr、unique_ptr等),以帮助自动管理内存。 9. **多态**:C++的多态性...

    c/c++帮助文档中文

    C语言是最早由Dennis Ritchie在贝尔实验室设计的,它是一种底层语言,强调过程化编程,对内存管理有极高的控制权。C语言的知识点包括但不限于: 1. **基本语法**:变量声明、数据类型(如int、char、float等)、...

    C/C++详细函数大全

    比如,`new`和`delete`是C++中的内存管理函数,它们与C语言的`malloc`和`free`类似但更加强大,可以处理类对象的构造和析构。C++标准库中还包含大量的STL(Standard Template Library)函数,如容器(如`vector`、`...

    林锐-高质量c/c++编程指南

    7. **内存管理**:讨论内存分配方式、常见内存错误及其对策、指针与数组的区别、指针参数如何传递内存、`free`和`delete`的操作机制、内存回收机制、避免“野指针”、`malloc/free`与`new/delete`的区别、内存耗尽时...

    动态内存分配与回收 c/c++

    9. **STL容器与内存管理**:C++标准模板库(STL)中的容器如`std::vector`, `std::list`, `std::map`等,内部实现了动态内存管理,用户无需直接调用`malloc`和`free`。 10. **异常安全**:在处理动态内存时,确保在...

    精通Matlab与C/C++混合程序设计(第三版) 配套光盘

    4. **内存管理**:由于Matlab和C/C++的内存管理机制不同,理解如何在两者间正确管理内存避免内存泄漏是混合编程中的重要一环。 5. **并发与多线程**:Matlab的并行计算工具箱可以与C/C++的多线程技术结合,实现高...

    C/C++内存编程

    在C/C++编程中,内存管理是至关重要的一个环节,因为它直接影响到程序的性能、稳定性和安全性。本篇将深入探讨这些主题,帮助你更好地理解和掌握C++中的内存管理。 首先,C++内存分为五个区域:栈(Stack)、堆...

    C语言/C++实现图书管理系统

    总的来说,"C语言/C++实现图书管理系统"项目涵盖了C语言和C++的基础知识,包括数据结构、内存管理、输入输出、控制结构、面向对象编程以及简单的错误处理。这个项目不仅能够提升编程技能,还能够锻炼解决问题和设计...

Global site tag (gtag.js) - Google Analytics