C语言内存讲解-详说内存分布和heap空间
目录
内存分布
变量
内存4区模型
开辟释放 heap 空间
使用 heap 空间
二级指针对应的 heap空间
内存分布
程序没有加载到内存前,可执行程序内部已经分好3段信息,分别为代码区(text)、数据区(data)和未初始化数据区(bss)3 个部分(有些人直接把data和bss合起来叫做静态区或全局区)。
代码区
存放 CPU 执行的机器指令。通常代码区是可共享的(即另外的执行程序可以调用它),使其可共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可。代码区通常是只读的,使其只读的原因是防止程序意外地修改了它的指令。另外,代码区还规划了局部变量的相关信息。
全局初始化数据区/静态数据区(data段)
该区包含了在程序中明确被初始化的全局变量、已经初始化的静态变量(包括全局静态变量和局部静态变量)和常量数据(如字符串常量)。
未初始化数据区(又叫 bss 区)
存入的是全局未初始化变量和未初始化静态变量。未初始化数据区的数据在程序开始执行之前被内核初始化为 0 或者空(NULL)。
程序在加载到内存前,代码区和全局区(data和bss)的大小就是固定的,程序运行期间不能改变。然后,运行可执行程序,系统把程序加载到内存,除了根据可执行程序的信息分出代码区(text)、数据区(data)和未初始化数据区(bss)之外,还额外增加了栈区、堆区。
代码区(text segment)
加载的是可执行文件代码段,所有的可执行代码都加载到代码区,这块内存是不可以在运行期间修改的。
未初始化数据区(BSS)
加载的是可执行文件BSS段,位置可以分开亦可以紧靠数据段,存储于数据段的数据(全局未初始化,静态未初始化数据)的生存周期为整个程序运行过程。
全局初始化数据区/静态数据区(data segment)
加载的是可执行文件数据段,存储于数据段(全局初始化,静态初始化数据,文字常量(只读))的数据的生存周期为整个程序运行过程。
栈区(stack)
栈是一种先进后出的内存结构,由编译器自动分配释放,存放函数的参数值、返回值、局部变量等。在程序运行过程中实时加载和释放,因此,局部变量的生存周期为申请到释放该段栈空间。
堆区(heap)
堆是一个大容器,它的容量要远远大于栈,但没有栈那样先进后出的顺序。用于动态内存分配。堆在内存中位于BSS区和栈区之间。一般由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收。
变量
局部变量:
概念:定义在函数内部的变量。
作用域:从定义位置开始,到包裹该变量的第一个右大括号结束。
生命周期:局部变量:从变量定义开始,函数调用完成。 --- 函数内部。
全局变量:
概念:定义在函数 外 部的变量。
作用域:从定义位置开始,默认到本文件内部。 其他文件如果想使用,可以通过声明方式将作用域导出。
生命周期: 程序启动开始,程序终止结束。 --- 程序执行期间。
static全局变量:
定义语法: 在全局变量定义之前添加 static 关键字。 static int a = 10;
作用域:被限制在本文件内部,不允许通过声明导出到其他文件。
生命周期:程序启动开始,程序终止结束。 --- 程序执行期间。
static局部变量:
定义语法: 在局部变量定义之前添加 static 关键字。
特性: 静态局部变量只定义一次。在全局位置。 通常用来做计数器。
作用域:从定义位置开始,到包裹该变量的第一个右大括号结束。
生命周期:程序启动开始,程序终止结束。 --- 程序执行期间
全局函数: 函数
定义语法: 函数原型 + 函数体
生命周期:程序启动开始,程序终止结束。 --- 程序执行期间。
static函数:
定义语法:static + 函数原型 + 函数体
static 函数 只能在 本文件内部使用。 其他文件即使声明也无效。
生命周期:程序启动开始,程序终止结束。 --- 程序执行期间。
内存4区模型
代码段:.text段。 程序源代码(二进制形式)。
数据段:只读数据段 .rodata段。初始化数据段 .data段。 未初始化数据段 .bss 段。
stack:栈。 在其之上开辟 栈帧。 windows 1M --- 10M Linux: 8M --- 16M
heap:堆。 给用户自定义数据提供空间。 约 1.3G+
当全局变量与局部变量命名冲突时采用就近原则
开辟释放 heap 空间
void *malloc(size_t size); 申请 size 大小的空间
返回实际申请到的内存空间首地址。 【我们通常拿来当数组用】
void free(void *ptr); 释放申请的空间
参数: malloc返回的地址值。
使用 heap 空间
空间时连续。 当成数组使用。
free后的空间,不会立即失效。 通常将free后的 地址置为NULL。
free 地址必须 是 malloc申请地址。否则出错。
如果malloc之后的地址一定会变化,那么使用临时变量tmp 保存。
代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>int main()
{//int arr[1000000] = {10, 20, 40};int *p = (int *)malloc(sizeof(int) * 10);//char *str = (char *)malloc(sizeof(char)*10);if (p == NULL){printf("malloc error\n");return -1;}char *tmp = p; // 记录malloc返回的地址值。用于free// 写数据到 malloc 空间。for (size_t i = 0; i < 10; i++){p[i] = i + 10;}// 读出malloc空间中的数据//for (size_t i = 0; i < 10; i++)//{// printf("%d ", *(p+i));//}for (size_t i = 0; i < 10; i++){printf("%d ", *p);p++;}// 释放申请的内存。free(tmp);p = NULL;system("pause");return EXIT_SUCCESS;
}
二级指针对应的 heap空间
申请外层指针: char **p = (char **)malloc(sizeof(char *) * 5);
申请内层指针:
for(i = 0; i < 5; i++){p[i] = (char *)malloc(sizeof(char) *10);}
使用: 不能修改 p 的值。
for(i = 0; i < 5; i++){strcpy(p[i], "helloheap");}
释放内层:
for(i = 0; i < 5; i++){free(p[i]);}
释放外层:
free(p);
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=29tl2ib8yb6sk
C语言内存讲解-详说内存分布和heap空间相关推荐
- C语言动态内存分配详解
文章目录 前言 一.为什么存在动态内存分配 1.已掌握的内存开辟方式 2.上述开辟空间方式的特点 3.为什么存在动态内存分配 二.动态内存函数的介绍 1.malloc 2.free 3.calloc ...
- linux内存管理详解,Linux内存管理图文讲解.pdf
Linux内存管理图文讲解 逻辑地址.线性地址.物理地址和虚拟地址 一.概念 物理地址(physical address) 用于内存芯片级的单元寻址,和处理器和 CPU 连接的地址总线相对应. 这个概 ...
- 【C语言】动态内存分配详解
目录 一.为什么有动态内存分配 二.动态内存分配函数 (1)malloc()函数 (2)calloc()函数 (3)realloc()函数 三.常见的动态内存错误 1.越界访问 2.内存泄漏 3.对N ...
- Nginx内存管理详解
目录: 1.Nginx内存管理介绍 2.Nginx内存池的逻辑结构 3.Nginx内存池的基本数据结构 4.内存池基本操作介绍 5.内存池管理源码详解 6.内存池使用源码详解 7.小结 1.Nginx ...
- 【C++】C++对象模型:对象内存布局详解(C#实例)
C++对象模型:对象内存布局详解 0.前言 C++对象的内存布局.虚表指针.虚基类指针解的探讨,参考. 1.何为C++对象模型? 引用<深度探索C++对象模型>这本书中的话: 有两个概念可 ...
- android内存问题详解--重要
转自:http://blog.csdn.net/dajian790626/article/details/9453993 第一种说法: 不用在意剩余内存的大小其实很多人都是把使用其他系统的习惯带过来 ...
- JVM 与 Linux 的内存关系详解
来源:美团技术团队 在一些物理内存为8g的服务器上,主要运行一个Java服务,系统内存分配如下:Java服务的JVM堆大小设置为6g,一个监控进程占用大约 600m,Linux自身使用大约800m. ...
- linux c语言 glibc 错误 munmap,Linux内存分配小结--malloc、brk、mmap
Linux的虚拟内存管理有几个关键概念: 1.每个进程都有独立的虚拟地址空间,进程访问的虚拟地址并不是真正的物理地址: 2.虚拟地址可通过每个进程上的页表(在每个进程的内核虚拟空间地址)与物理地址进行 ...
- C语言程序设计 | 动态内存管理:动态内存函数介绍,常见的动态内存错误,柔性数组
动态内存管理目录: 动态内存函数的介绍 常见的动态内存函数的错误 柔性数组 为什么会有动态内存管理呢 我们在日常使用中,创建一个数组,一个变量时都会开辟空间 如: int a; //在栈上开辟一个四字 ...
最新文章
- LSTM之父重提30年前的「快速权重存储系统」:线性Transformer只是它的一种变体...
- IntelliTest实战直通车(上集)
- 面试中遇到过的闭包~
- 从windows server的文件服务到分布式文件服务(二)
- vscode连接远程服务器 SSH
- Python 模拟微博登陆,亲测有效!
- 不止音箱,百度还发布了这些AI产品,还有参会者的10个小建议
- 力扣-606. 根据二叉树创建字符串
- asp.net mvc 如何调用微信jssdk接口:分享到微信朋友(圈)| 分享到qq空间
- 计算机办公软件考证教学总结,考证经历——办公软件的套路
- python美女源代码_python程序员爬取百套美女写真集,同样是爬虫,他为何如此突出...
- 金山打字通五笔介绍及讲解
- 【python】chardet函数用法
- RCNN算法思想简单讲解概述————(究极简单的讲述和理解)
- 迭代学习控制方式Simulink建模与仿真
- unity导入模型昏暗(对比度低)解决办法
- HTML学习的一些笔记
- 比JMeter还轻量的压力测试工具是谁?Siege
- HTML人物介绍、个人设计web前端大作业、贝聿铭人物介绍(带报告3000字)
- ECharts加载省份地图
热门文章
- 再不入坑就晚了,深度神经网络概念大整理,最简单的神经网络是什么样子?
- arcgis统计重复值及筛选重复值
- 七牛云直播SDK之推流端快速开发
- 赵国栋:大数据时代经济发展转型之道
- 程序员:我是凭自己本事单身,为啥要将就对象谈恋爱
- 实时监控窗口分辨率实现网页等比例缩放
- 只用1分钟,搞定500份简历筛选!
- 基于51单片机+SHT30设计的环境温度与湿度检测设备(IIC模拟时序)
- 什么是虚拟机?虚拟机有什么用? 虚拟机的特点?
- android 关闭odex优化,[Android] 配置安卓模拟器,使得dex文件不被优化成odex