栈、堆、全局区/静态存储区、常量区、代码段、到底是什么?

news2024/11/15 7:04:28

一、程序运行内存分布图

我们知道一个由我们编写好的程序,运行时,我们的程序中写的代码,定义的变量,写的函数、for 循环等等,这些运行时都分布在内存中的哪里吗?
一下是一个程序运行时 内存的各个区域的分布
在这里插入图片描述
详细的每个区域存放的内容如下

二、栈

没错,是不是想到了 数据结构的栈:
在这里插入图片描述
栈 遵循后进先出先进后出的 存储顺序,那么这个栈和我们的程序运行又有什么大的联系呢?
看一段代码示例:

#include <stdio.h>
void Fun4()
{
	printf("4\n");
}
void Fun3()
{
	printf("3\n");
	Fun4();
}
void Fun2()
{
	printf("2\n");
	Fun3();
}
void Fun1()
{
	printf("1\n");
	Fun2();
}
int main()
{
	Fun1();
	return 0;
}

是的 是一段非常无聊且易懂的代码,函数调用关系图为:
在这里插入图片描述
调试代码并 打开VS2017 的堆栈窗口
在这里插入图片描述
该图表示函数的调用过程 自底向上调用,函数执行完之后,该函数生命周期结束,函数退出,就像栈的 pop 操作,直到所有的函数调用完之后,栈底只有一个 main 函数 , main 函数执行完之后 最终整个程序也结束掉。
在这里插入图片描述
栈的空间一般是由系统分配的,一般存储着局部变量、函数参数、函数返回值等,一般大小为 1M 、2M 等 ;
在内存中的位置为:
且是向下分配空间
在这里插入图片描述
示例局部变量定义:

#include <stdio.h>
int main()
{
	int a = 0;
	int b = 0;
	int c = 0;
	printf("%p\n", &a);
	printf("%p\n", &b);
	printf("%p\n", &c);
	return 0;
}

在这里插入图片描述
可以看到 局部变量 a b c 的地址依次变低,也证实了栈的空间地址分配时 从高到低

三、堆

注意 这个堆 可不是 数据结构里面的堆, 这里的堆 是专门开辟出来 给我们程序员 动态申请内存使用的,例如 我们 malloc 、new 出来的空间 这部分都在堆上
与栈相反的是,我们动态申请的空间是 由低地址到高地址的
在这里插入图片描述
代码示例:

#include <stdio.h>
int main()
{
	int *p = (int*)malloc(8);
	int *p1 = (int*)malloc(8);
	printf("%p\n", p);
	printf("%p\n", p1);
	//同时 使用完申请的空间之后要记得释放,否则会造成内存泄漏,
	//且释放之后,不能再次释放 否则会造成非法操作、越界访问,导致程序崩溃
	free(p);
	p = NULL;
	free(p1);
	p1 = NULL;
	return 0;
}

打印结果:
在这里插入图片描述

3.2 堆与栈的区别

空间管理方式不同:

1.栈上的空间由系统分配并管理、不需要我们关心申请与释放
2.堆上的空间是我们自己申请并负责释放、如果忘记释放会造成内存泄漏、多次释放也会导致越界访问、非法操作、甚至导致程序崩溃问题等,这是需要我们程序员自己注意的地方

内存分配方向不同

1.栈上的空间是从高地址向低地址分配
2.堆上的空间是从低地址向高地址分配

分配效率不同

1.栈是由系统分配管理,更加贴合系统底层、效率更高
2.堆的申请和释放是由库函数支持,由我们自己手动调用库函数进行申请内存和释放内存,且容易产生内存碎片的问题,效率低于栈

存放内容不同

1.栈主要存放局部变量、函数返回值、函数参数、函数地址等、程序运行过程中的函数调用就是栈来完成的、函数调用逐个入栈、调用完成之后逐个弹出
2.堆主要为我们动态申请空间服务,为我们开辟空间

四、全局区/静态存储区

这里主要存放 全局变量和 静态变量、生命周期覆盖整个程序、直到程序结束,生命周期结束、不过这里还细分了是否初始化的全局变量和静态变量,但是大体是在一个区域内存放
例如:

#include <stdio.h>
int n = 0;//全局区
int arry[10];//全局区
int main()
{
	static int i = 0;//静态存储区
	return 0;
}

五、常量区

例如如下:

string str1 = "helloworld";
int n = 6;
"helloworld 和 6 都属于常量、不允许被修改

六、代码区

存放代码、不允许被修改,也就是我们所写的函数,是存放在这里的
代码区中的东西是随整个程序一起的,启动时 生、结束时 亡
有时候放在代码段的不只是代码,还有const类型的常量,还有字符串常量。(const类型的常量、字符串常量有时候放在常量区有时候放在代码段,取决于平台)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/196754.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言字符串指针(指向字符串的指针)详解

C语言中没有特定的字符串类型&#xff0c;我们通常是将字符串放在一个字符数组中&#xff0c;这里演示一下&#xff1a;#include<stdio.h> #include<string.h>intmain(){ char str[]"http://csdn.net"; int len strlen(str), i; //直接输出字符串 printf…

一套完全开源,支持多租户,界面配置单点的后端框架JVS,赶紧收藏

今天推荐的这个项目是「JVS数据全家桶中的 JVS微服务框架」—— 是一个免费开源的中后台模版&#xff0c;使用了最新的 vuespring cloud 主流技术开发&#xff0c;开箱即用的中后台前端解决方案&#xff0c;可以直接商用&#xff0c;并且这个脚手架上做了很多商业上的扩展&…

day19 二叉树 | 654、最大二叉树 617、合并二叉树 700、二叉搜索树中的搜索 98、验证二叉搜索树

题目 654、最大二叉树 给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下&#xff1a; 二叉树的根是数组中的最大元素。左子树是通过数组中最大值左边部分构造出的最大二叉树。右子树是通过数组中最大值右边部分构造出的最大二叉树。 通过给定的数组构…

数据中心转型利润中心:数据如何赋能零售行业营销升级?

通过大数据来提升营销效果已经是零售行业不同业态都绕不过去的话题。以往&#xff0c;市场团队在进行投放时需要依靠营销团队和销售团队的经验来判断&#xff0c;这样的营销策略较为粗放&#xff0c;对用户的感知也不精准&#xff0c;一般都是在海量投放后被动的等待营销反馈。…

C++代码优化(2):条款5~12

"然后自然老去吧&#xff0c;别再依依惜别了"条款5:了解C默默编写并调用了哪些函数(1)小试牛刀地回顾C编译器为类提供的默认函数很多人知道是有6个的。默认构造、拷贝构造、赋值重载、析构函数、重载取地址运算符&#xff0c;但是在C11更新后&#xff0c;又为类对象增…

软件测试项目实战,我们拿到项目第一步应该怎么做【附过程文档】

对于从事软件研发的组织来说&#xff0c;工作类型至少包括项目管理、产品设计、编码、测试、质量保证和软件配置管理&#xff0c;以及其它人员&#xff0c;如文档编制人员和美工人员/系统硬件管理人员等。根据职能需要&#xff0c;可以以半独立方式进行部门和项目的矩阵管理&am…

Let’s Encrypt共建安全的互联网

导读最近关于沃通和 StartCom 这两家 CA 公司的消息让人们再次关注到了网络隐私和安全的问题。随着 Mozilla、苹果和谷歌对这两家 CA 公司处罚落定&#xff0c;很多使用这两家 CA 所签发证书的网站纷纷寻求新的证书签发商。这里面固然有不少可信赖的 CA 公司可以提供服务&#…

UniRx之基本语法格式

前言 想要更好的去学习UniRx&#xff0c;我们最好是先理解UniRx 的语法格式。就像我们去学习英语或者汉语一样&#xff0c;理解了基本的语法规则后&#xff0c;再学其他的就信手拈来了。 语法示例 下面我们来看一个最简单的示例&#xff0c; Observable.EveryUpdate().Where…

Git安装,配置及Gitee项目代码pull到本地

一、Git安装从git官网下载&#xff1a;https://git-scm.com/downloads选择适合的版本进入下载&#xff0c;然后傻瓜式安装直到结束。检查安装是否成功&#xff1a;进入任意文件夹点击右键选择Git Bash Here进行基本配置输入如下命令&#xff1a;git --version就会显示当前安装的…

【Windows】ip地址修改器v5.0.5.4

简介 IP地址修改器&#xff0c;一款能够快速的切换IP地址&#xff0c;在几个不同的固定IP之间进行切换&#xff0c;手动输太麻烦&#xff0c;所以可以用到这款IP地址修改器&#xff01; 下载 ip地址修改器v5.0.5.4 软件介绍 程序主要原理还是利用了WMI的Win32_NetworkAda…

二叉搜索树,平衡二叉树,红黑树,B树,B+树

文章目录二叉树&#xff08;BT&#xff09;1. 满二叉树2. 完全二叉树二叉搜索树&#xff08;BST&#xff09;平衡二叉搜索树&#xff08;AVL&#xff09;1. 定义2. 如何保持平衡——旋转红黑树&#xff08;RBTree&#xff09;1.定义2.红黑规则3.插入规则B树1.定义2.在磁盘系统中…

云存储、云计算与分布式存储、分布式计算是一回事吗?

随着互联网的蓬勃兴起&#xff0c;大数据、人工智能、物联网、云计算与云存储等这些专业词汇在大众视野内出现的频率越来越高&#xff0c;再加上近几年分布式技术异军突起&#xff0c;更使得分布式存储、分布式计算等成为热词。然而&#xff0c;很多人对这些名词都一知半解&…

HTML5+CSS3(七)-全面详解(学习总结---从入门到深化)

目录 字体属性 color font-size font-weight font-style font-family 学习效果反馈 背景属性一 background-color属性 background-image属性 background-repeat属性 学习效果反馈 背景属性二 background-size属性 background-position属性 background-attachment属性…

Utools的安装与使用

Utools的安装与使用 新一代效率工具平台. 自由组合插件应用&#xff0c;打造专属你的趁手工具集&#xff0c;我们可以根据自己需求下载对应插件&#xff0c;然后通过Utools启动插件&#xff0c;不用向以前那样不同的插件需要找到对应插件地址。我们也可以通过设置全局快捷键快速…

ESP-IDF:字符串中字符转为链表结点入栈(使用STL stack),然后打印栈中内容

ESP-IDF:字符串中字符转为链表结点入栈(使用STL stack),然后打印栈中内容 /字符串中字符转为链表结点入栈(使用STL stack),然后打印栈中内容/ #include typedef struct LINKNODE20 { struct LINKNODE20 * next; }linknode20; typedef struct MYCHAR20 { linknode20 node; ch…

C++ STL源码剖析 笔记

写在前面 记录一下《C STL源码剖析》中的要点。 一、STL六大组件 容器&#xff08;container&#xff09;&#xff1a; 各种数据结构&#xff0c;用于存放数据&#xff1b;class template 类泛型&#xff1b;如vector, list, deque, set, map&#xff1b; 算法&#xff08;a…

LeetCode刷题系列 -- 113. 路径总和 II

给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。叶子节点 是指没有子节点的节点。示例 1&#xff1a;输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum 22输出&#x…

Java:函数与数组的相关代码题目

引言&#xff1a; 放松一段时间&#xff0c;今天又重新开始与大家来学习&#xff0c;假期正是我们反超别人的最佳时间&#xff0c;大家要抑制自己的情绪&#xff0c;低头学习。没有任何一种成功是短时间可以得到的&#xff0c;我们要做的就是&#xff0c;沉下心来&#xf…

偶数科技入选 IDC 中国分布式数据库报告,获 Innovator 殊荣

C Innovator 近日&#xff0c;全球知名咨询研究机构 IDC 发布了《中国分布式关系型数据库》研究报告&#xff0c;通过调研 CIO、IT 负责人、投资机构和众多厂商&#xff0c;评选出该领域综合表现突出的创新型厂商。偶数科技凭借其新一代云原生数据库 OushuDB 和实时湖仓一体创新…

rocketmq源码打包

背景&#xff1a;升级broker版本&#xff0c;并修改broker源代码步骤&#xff1a;1.下载源码&#xff0c;地址&#xff1a;https://rocketmq.apache.org/download/binary是编译好的可以直接使用&#xff0c;source是还没编译过的源代码&#xff0c;需要自行编译。因为我需要修改…