这是原文的链接
存储类(Storage Class)
简单来说,存储类就是C语言中存储变量的地方的类型
分为动态存储区,静态存储区
动态存储区
栈(Stack)
- 其增长方向:自顶向下增长
- 有内存空间的限制
存储内容
- 函数形参,在调用函数时给形参分配空间
- 函数内的自动变量(即普通变量)
- 函数调用时的现场保护和返回地址(即函数调用语句的下一句可执行语句)
- 在函数调用开始时分配存储空间,函数结束时释放存储空间
- 函数调用结束时,局部变量先出栈,接着是形参,最后栈指针指向最开始存储的地址来进行下一条指令
堆(Heap)
- 程序员自定义存储空间
- 使用后,需要手动释放内存,不然会造成内存泄露
静态存储区
.data段
- 存放非零全局变量、静态局部变量
.bss段(Block Started by Symbol)
- 存放未初始化的全局变量、静态局部变量
- 运行时,由系统初始化,即清零。一般要自己写
.ROData(文本常量区)
- 存放字符串常量
char *p="linux"; // 定义了一个分配在栈上占4字节的指针指向了一个分配在文本常量区上占6字节的字符串
.text段(代码区)
- cup执行的机器指令部分(函数体的二进制代码)
- 属性只读,为了防止程序由于意外事故而修改自身指令
作用域
作用域即变量或函数起作用的范围
- 文件作用域
- 代码作用域
生命周期
- 永久
- 临时
链接属性
链接属性有以下3种:
- 外链接
- 内链接
- 无链接
宏定义 和 inline内联函数 链接属性为 无链接
总结
类型 | 存储类 | 作用域 | 生命周期 | 链接属性 |
---|---|---|---|---|
普通全局变量 | .data段/.BSS段 | 文件作用域 | 永久 | 外链接 |
静态全局变量 | .data段/.BSS段 | 文件作用域 | 永久 | 内链接 |
普通局部变量 | 栈 | 代码作用域 | 临时 | 无链接 |
静态局部变量 | .data段/.BSS段 | 代码作用域 | 永久 | 无链接 |
普通函数 | .text段 | 文件作用域 | 永久 | 外链接 |
静态函数 | .text段 | 文件作用域 | 永久 | 内链接 |
堆与栈的比较
类型 | Stack | Heap |
---|---|---|
生长方向 | 向地址减小的方向增长 | 向地址增大的方向增长 |
分配方式 | 动态分配与静态分配 | 动态分配 |
碎片问题 | 无此问题 | 过多使用会造成内存不足 |
申请后系统响应 | 无可用空间报异常提示栈溢出 | 系统分配申请的内存到空闲地址链表中 |
分配效率 | 相对高 | 相对低 |
申请大小 | 系统预先规定好大小 | 系统可用内存 |
申请效率 | 相对快 | 相对慢,容易产生内容碎片 |
存储内容 | 看上面 | 一般在堆的头部用1字节存放堆的大小,其他程序员安排 |
存取效率 | 相对快,char s[]="Hello";在运行时赋值;数组比指针要快一些 | 相对慢;char *s="Hello";在编译时确定 |
最后附上一张内存分布的图片
注:本文内容部分来自互联网整理,部分来自个人经验总结;本文将持续收集更新,欢迎留言补充!