c语言和内存 pdf,C语言内存分配.pdf

C 语言内存分配语言内存分配语言内存分配语言内存分配 分类 C C 基础2011 05 02 14 02 278人阅读 评论 1 收藏 举报 C 语言程序编译的内存分配语言程序编译的内存分配语言程序编译的内存分配语言程序编译的内存分配 1 栈区栈区栈区栈区 stack 编译器自动分配释放编译器自动分配释放编译器自动分配释放编译器自动分配释放 主要存放函数的参数值主要存放函数的参数值主要存放函数的参数值主要存放函数的参数值 局部变量值局部变量值局部变量值局部变量值 等等等等 2 堆区堆区堆区堆区 heap 由程序员分配释放由程序员分配释放由程序员分配释放由程序员分配释放 3 全局区或静态区全局区或静态区全局区或静态区全局区或静态区 存放全局变量和静态变量存放全局变量和静态变量存放全局变量和静态变量存放全局变量和静态变量 程序结束时由系统释放程序结束时由系统释放程序结束时由系统释放程序结束时由系统释放 分为全分为全分为全分为全 局初始化区和全局未初始化区局初始化区和全局未初始化区局初始化区和全局未初始化区局初始化区和全局未初始化区 4 字符常量区字符常量区字符常量区字符常量区 常量字符串放与此常量字符串放与此常量字符串放与此常量字符串放与此 程序结束时由系统释放程序结束时由系统释放程序结束时由系统释放程序结束时由系统释放 5 程序代码区程序代码区程序代码区程序代码区 存放函数体的二进制代码存放函数体的二进制代码存放函数体的二进制代码存放函数体的二进制代码 例例例例 main c int a 0 全局初始化区 char p1 全局未初始化区 void main int b 栈 char s bb s 在栈 bb 在常量区 char p2 栈 char p3 123 其中 123 0 常量区常量区常量区常量区 p3 在栈区在栈区在栈区在栈区 static int c 0 全局区 p1 char malloc 10 10 个字节区域在堆区 strcpy p1 123 123 0 在常量区 编译器 可能可能可能可能 会优化为和 p3 的指向同一块 区域 一个一个一个一个 C 程序占用的内存可分为以下几类程序占用的内存可分为以下几类程序占用的内存可分为以下几类程序占用的内存可分为以下几类 一一一一 栈栈栈栈 这是由编译器自动分配和释放的区域 主要存储函数的参数 函数的局部变 量等 当一个函数开始执行时 该函数所需的实参 局部变量就推入栈中 该函 数执行完毕后 之前进入栈中的参数和变量等也都出栈被释放掉 它的运行方式 类似于数据结构中的栈 二二二二 堆堆堆堆 这是由程序员控制分配和释放的区域 在 C 里 用 malloc 函数分配的空间 就存在于堆上 在堆上分配的空间不像栈一样在某个函数执行完毕就自动释放 而是一直存在于整个程序的运行期间 当然 如果你不手动释放 free 函数 这些 空间 在程序运行结束后系统也会将之自动释放 对于小程序来说可能感觉不到 影响的存在 但对于大程序 例如一个大型游戏 就会遇到内存不够用的问题了 三三三三 全局区全局区全局区全局区 C 里的全局变量和静态变量存储在全局区 它们有点像堆上的空间 也是持 续存在于程序的整个运行期间 但不同的是 他们是由编译器自己控制分配和释 放的 四四四四 文字常量区文字常量区文字常量区文字常量区 例如 char c 123456 则 123456 为文字常量 存放于文字常量区 也 由编译器控制分配和释放 五五五五 程序代码区程序代码区程序代码区程序代码区 存放函数体的二进制代码 2 例子例子例子例子 一一一一 int a 0 全局区 void main int b 栈 char s abc s 在栈 abc 在文字常量区 char p1 p2 栈 char p3 123456 123456 在常量区 p3 在栈上 static int c 0 全局区 p1 char malloc 10 p1 在栈 分配的 10 字节在堆 p2 char malloc 20 p2 在栈 分配的 20 字节在堆 strcpy p1 123456 123456 放在常量区 编译器可能将它与 p3 所指向的 123456 优化成一个地方 3 例子例子例子例子 二二二二 返回 char 型指针 char f s 数组存放于栈上 char s 4 1 2 3 0 return s 返回 s 数组的地址 但函数运行完 s 数组就被释放了 void main char s s f printf s s 打印出来乱码 因为 s 所指向地址已经没有数据 还有就是函数调用时会在栈上有一系列的保留现场及传递参数的操作函数调用时会在栈上有一系列的保留现场及传递参数的操作函数调用时会在栈上有一系列的保留现场及传递参数的操作函数调用时会在栈上有一系列的保留现场及传递参数的操作 栈的空间大小有限定栈的空间大小有限定栈的空间大小有限定栈的空间大小有限定 vc 的缺省是 2M 栈不够用的情况一般是程序中分配了大 量数组和递归函数层次太深 有一点必须知道 当一个函数调用完返回后它会释当一个函数调用完返回后它会释当一个函数调用完返回后它会释当一个函数调用完返回后它会释 放该函数中所有的栈空间放该函数中所有的栈空间放该函数中所有的栈空间放该函数中所有的栈空间 栈是由编译器自动管理的 不用你操心 堆是动态分配内存的堆是动态分配内存的堆是动态分配内存的堆是动态分配内存的 并且你可以分配使用很大的内存 但是用不好会产生 内存泄漏 并且频繁地频繁地频繁地频繁地 malloc 和和和和 free 会产生内存碎片会产生内存碎片会产生内存碎片会产生内存碎片 有点类似磁盘碎片 因为因为因为因为 C 分配动态内存时是寻找匹配的内存的分配动态内存时是寻找匹配的内存的分配动态内存时是寻找匹配的内存的分配动态内存时是寻找匹配的内存的 而用栈则不会产生碎片而用栈则不会产生碎片而用栈则不会产生碎片而用栈则不会产生碎片 在栈上 存取数据比通过指针在堆上存取数据快些 一般大家说的堆栈和栈是一样的 就 是栈 stack 而说堆时才是堆 heap 栈是先入后出的 一般是由高地址向低地址生 长 堆 heap 和栈 stack 是 C C 编程不可避免会碰到的两个基本概念 首先 这两个概念都可以在讲数据结构的书中找到 他们都是基本的数据结构 虽然栈 更为简单一些 在具体的 C C 编程框架中 这两个概念并不是并行的 对底层 机器代码的研究可以揭示 栈是机器系统提供的数据结构 而堆则是 C C 函数 库提供的 具体地说 现代计算机 串行执行机制 都直接在代码底层支持栈的 数据结构 这体现在 有专门的寄存器指向栈所在的地址 有专门的机器指令完 成数据入栈出栈的操作 种机制的特点是效率高 支持的数据有限 一般是整数 指针 浮点数等系统直接支持的数据类型 并不直接支持其他的数据结构 因为 栈的这种特点 对栈的使用在程序中是非常频繁的 对子程序的调用就是直接利 用栈完成的 机器的 call 指令里隐含了把返回地址推入栈 然后跳转至子程序地 址的操作 而子程序中的 ret 指令则隐含从堆栈中弹出返回地址并跳转之的操作 C C 中的自动变量是直接利栈的例子 这也就是为什么当函数返回时 该函数 的自动变量自动失效的原因 和栈不同 堆的数据结构并不是由系统 无论是机器系统还是操作系统 支持 的 而是由函数库提供的 基本的 malloc realloc free 函数维护了一套内部的堆数 据结构 当程序使用这些函数去获得新的内存空间时 这套函数首先试图从内部 堆中寻找可用的内存空间 如果没有可以使用的内存空间 则试图利用系统调用 来动态增加程序数据段的内存大小 新分配得到的空间首先被组织进内部堆中 去 然后再以适当的形式返回给调用者 当程序释放分配的内存空间时 这片内 存空间被返回内部堆结构中 可能会被适当的处理 比如和其他空闲空间合并成 更大的空闲空间 以更适合下一次内存分配申请 这套复杂的分配机制实际上 相当于一个内存分配的缓冲池 Cache 使用这套机制有如下若干原因 1 系统调用可能不支持任意大小的内存分配 有些系统的系统调用只支持固定 大小及其倍数的内存请求 按页分配 这样的话对于大量的小内存分类来说会造 成浪费 2 系统调用申请内存可能是代价昂贵的 系统调用可能涉及用户态和核心态的 转换 3 没有管理的内存分配在大量复杂内存的分配释放操作下很容易造成内存碎片 堆和栈的对比堆和栈的对比堆和栈的对比堆和栈的对比 从以上知识可知 栈是系统提供的功能 特点是快速高效 缺点是有限制 数据不灵活 而堆是函数库提供的功能 特点是灵活方便 数据适应面广泛 但 是效率有一定降低 栈是系统数据结构 对于进程 线程是唯一的 堆是函数库 内部数据结构 不一定唯一 不同堆分配的内存无法互相操作 栈空间分静态分 配和动态分配两种 静态分配是编译器完成的 比如自动变量 auto 的分配 动 态分配由 alloca 函数完成 栈的动态分配无需释放 是自动的 也就没有释放函 数 为可移植的程序起见 栈的动态分配操作是不被鼓励的 堆空间的分配总是 动态的 虽然程序结束时所有的数据空间都会被释放回系统 但是精确的申请内 存 释放内存匹配是良好程序的基本要素

展开阅读全文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值