static修饰的对象在内存中的存储及其用法

一、static修饰的变量在内存中的存储位置

        static关键字无论是在C语言还是C++中都有着极其重要的作用,那么对于static来说,它修饰的对象是存储在内存的哪个位置呢?它的作用与它在内存中的位置有什么联系?还有它都适用于哪些场景,各自有什么特点......要想了解这些,就必须深入考究它的内里。

        首先,我们先来谈一谈static修饰的对象到底存储在哪里呢?

1.1内存空间的分布

        如上图我们可知,内存共分为栈区、堆区、全局区域、常量区、代码区,在我们日常写代码时,所生成的主函数、调用函数都是由系统调用栈进行维护和释放,而一些int、float等类型的变量都是在栈中开辟相应的空间,栈由系统调用,但却空间较小,一般只有1M(或2M),但是在编译器中,我们也可手动调节。

        虽说栈有着速率快,调用方便、空间碎片少等优点,但却解决不了所有的问题,比如说我们要申请一大块内存空间,用来存储数据,这时栈就显得有些捉襟见肘了,这时,我们就要使用malloc、calloc或者new在堆上申请空间。在堆上申请的空间,不是由系统支配,而是由程序员进行申请和释放,所以在C++中内存泄露问题是所有C++老铁的一块心病啊。所以在编写代码时要时刻谨记内存申请释放的问题。

        而全局区(静态区)中存放的则是全局变量和静态变量,这里面的数据生命周期较长,通常会随着程序的结束而被释放。

        代码区,是编译器生成的一个exe区段,拥有可读和可执行属性,但是实际上如果不开dep数据执行保护,所有的区段都是可执行的。

        看到这里老铁们应该对内存有了一定的认识,也一定知道了static修饰的静态变量必然是存放在静态区中的,那么接下来我们便来继续剖析static成员特点及应用场景。

二、static的用法和作用

1、static修饰的变量可以延长生命周期,因为其存放在静态区中,所以当在一个函数中建立一个static变量时,该函数栈帧销毁时,在其中建立的变量依旧存在,当下次再次调用该函数时,static变量也同样是原来的。但是需要注意的是:在某一个函数中创建的static变量只能在该函数中进行调用,在外面则无法使用。

2、static修饰的对象具有隐藏的作用,当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。

3、在静态区中,所有的字节都被默认为0x00,所以static的变量在初始化时,如果不主动指定,则统一被初始化为0,这和静态区的特性息息相关。

4、在C++类中,static的用法如下:

(1)第一条和1有些相似,就是在类内的函数中static变量的作用范围仅为函数内部,该变量只被分配一次内存。

(2)在模块内的static变量可以被模块内所有的函数所使用,但不可被其他模块所使用。

(3)在模块内static函数可以被模块内的其他函数所调用,但不能被模块外的任何函数调用。

(4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝。

(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。

三、static函数能不能被virtual修饰

        关于virtual修饰static函数的问题,我们应该从虚函数的调用着手,要知道虚函数是通过各自的指针所调用,而他们的虚函数指针则是被存放在一个虚函数表中,这个虚函数表通常也是通过它的指针所访问,而它的指针被存放在对象中,是不是这里听起来很晕,所以我们再梳理一下,我们要想访问某个虚函数,需要在对象中找到虚函数表的指针,通过指针找到虚函数表,而虚函数表是一个指针数组,里面存放的是一个个虚函数的指针,所以我们只需在虚函数表中通过指针访问虚函数即可,如此一来是不是条理就清晰了许多。

        讲完虚函数的知识,我们进而就可以说一说static函数到底能不能被virtual所修饰。

        之上我们了解到因为static函数为整个类所有,不接收this指针,所以static成员不属于任何对象或实例,虚函数的实现是为每一个对象分配一个vptr指针,而vptr是通过this指针调用的,所以不能为virtual。

四、static成员什么时候被初始化

        static被初始化可以分为两个方面,一是在C中,二是在C++中。

        static变量只被初始化一次,之后可以被重复赋值,而在主程序开始之前,系统就已经为其分配好了空间,但是由于C++和C又有一些区别,所以在初始化的节点有些不一致。

        在C中,当系统为static变量初始化完成后,就会立即初始化。

        在C++中,因为引入了对象,所以在实例化时要进行构造,结束后要进行析构,所以有时构造就不单单是进行变量的初始化了,还有可能是进行动态内存申请等操作,所以static变量是在执行相关代码时进行初始化的。

五、总结

        关于static的相关知识,在之前就已经写过一篇博客了,但是由于当时学的比较粗浅(当然现在也是),只是比当初的自己了解的多了些,所以针对static又做了一篇文章,算是对大家的一种分享,也是对自己学习的一些总结,文章难免有不妥之处,有老铁们看出,还望不吝赐教。

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

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

相关文章

15.数据库简介+MySQl使用+SQL语句

文章目录 数据库简述一.数据库简介DB1.定义:2.DBMS数据库管理系统3.数据库分类 二.MySQL的安装1.安装步骤2.MySQL数据库图形管理工具3.mysql程序常用命令4.MySQL字符集及字符序5.Navicat快捷键操作 三.MySQL数据库基本操作 .........................................表管理一.…

RPC远程过程调用--Thrift

RPC远程过程调用–Thrift 简介 Thrift是一个由Facebook开发的轻量级、跨语言的远程服务调用框架,后进入Apache开源项目。支持通过自身接口定义语言IDL定义RPC接口和数据类型,然后通过编译器生成不同语言代码,用于构建抽象易用、可互操作的R…

黄子韬揭秘徐艺洋与EXO的不解之缘

黄子韬揭秘:徐艺洋与EXO的不解之缘在娱乐圈的繁华与喧嚣中,总有一些不为人知的故事,它们或温馨、或励志,或是感叹命运的奇妙。近日,黄子韬在一档热门综艺节目中意外爆料,揭开了徐艺洋与EXO之间鲜为人知的秘…

ffmpeg使用bmp编码器把bgr24编码为bmp图像

version #define LIBAVCODEC_VERSION_MAJOR 60 #define LIBAVCODEC_VERSION_MINOR 15 #define LIBAVCODEC_VERSION_MICRO 100 note 不使用AVOutputFormat code void CFfmpegOps::EncodeBGR24ToBMP(const char* infile, const char* width_str, const char* height_str…

IT之家最新科技热点

人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 目录 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌…

使用Java连接数据库并且执行数据库操作和创建用户登录图形化界面(3)专栏里有上两步的源代码

创建用户登录程序,验证用户账号和密码信息是否在数据库student中的用户表tb_account中存在。用户登录界面如下图所示: 当单击“登录”按钮时,处理以下几种情况: (1)用户名未输入,提示用户名不能…

业务模型扩展字段存储

构建业务模型时,通常模型会设置扩展信息,存储上一般使用JSON格式存储到db中。JSON虽然有较好的扩展性,但并没有结构化存储的类型和非空等约束,且强依赖代码中写入/读取时进行序列化/反序列化操作, 当扩展信息结构简单且…

代码随想录第37天|动态规划

01背包理论基础 参考 01背包: 每个物品只有一个, 只要选或不选两个选项 暴力解法: 回溯法枚举 dp[i][j]: i 表示 0 ~ i 的物品, j 表示容量, 数值表示当前的最大价值递推公式: max(dp[i-1][j], dp[i-1][j-weight[i]] value[i])初始化: j 0 时, 无法放任何有价值的物品, d…

ASP.Net.WebAPI和工具PostMan

1.WebAPI概述 1.1 WebAPI WebAPI 是一种传统的方式,用于构建和暴露 RESTUI风格的Web服务。它提供了丰富的功能和灵活性,可以处理各种HTTP请求,并支持各种数据格式,如JSON、XML等。 WebAPI使用控制器(Controllers)和动作方法(Ac…

【计算机网络仿真】b站湖科大教书匠思科Packet Tracer——实验10 IPv4地址 — 构造超网(无分类编址)

一、实验目的 1.加深对构造超网的理解; 二、实验要求 1.使用Cisco Packet Tracer仿真平台; 2.观看B站湖科大教书匠仿真实验视频,完成对应实验。 三、实验内容 1.构建网络拓扑; 2.根据各网络所指定的地址块完成以下工作&#…

携手亚马逊云科技,维塑科技推出运动健康领域首个AI大模型

导读:生成式AI运动健康,将如何改变我们的生活? 人工智能技术正不断重塑着我们的工作、生活方式。那么,AI能否改善我们的健康状况呢?AI大模型在运动健康领域的探索为我们带来新的想象。 2023年,全球领先的AI…

java之命令执行审计思路

1 漏洞原理 因用户输入未过滤或净化不完全,导致Web应用程序接收用户输入,拼接到要执行的系统命令中执行。一旦攻击者可以在目标服务器中执行任意系统命令,就意味着服务器已被非法控制。 2 审计中常用函数 一旦攻击者可以在目标服务器中执行…

Redis发布、订阅模式(Pub/Sub)详解

Redis发布、订阅模式(PUB-SUB)详解 Redis的发布订阅(Pub/Sub)机制是一种消息通信模式,用于消息的广播。它允许多个客户端订阅(Subscribe)特定的频道(Channel)&#xff0c…

Docker镜像拉去不了解决方案

原理&工具 使用海外的服务器拉去镜像,压缩为tar包,传输到本地在本地运行 服务器:这里我使用的是AWS的服务器,新用户注册免费使用1年(流量超了就不免费了,一般用不完,还有使用 Cloudflare …

【ARM CoreLink 系列 7.2 -- TZC-400 错误状态寄存器使用详细介绍】

文章目录 TZC-400 错误信息使用Fail address low registerFail address high registerFail control registerFail ID registerTZC-400 错误信息使用 Fail address low register 在 ARM TZC-400 设备中,每个过滤单元都有一个 fail_address_low_<x> 寄存器,其中 <x&g…

5.How Fast Should You Be When Learning?(你应该用多快的速度学习? (二))

Are you failing to reach an ideal or you dont know what the ideal is? 你是否没有达到理想状态&#xff0c;或者不知道理想状态是什么? A lot of learing involves having a mental representation of what the ideal performance ought to be, a method or approach t…

【计算机图形学 | 基于MFC三维图形开发】期末考试知识点汇总(下)

文章目录 视频教程第四章 二维变换与裁剪矩阵基础回顾二维几何变换之 平移二维几何变换之 比例二维几何变换之 旋转二维几何变换之 反射复合变换直线裁剪&#xff1a;Cohen-Sutherland 算法直线裁剪&#xff1a;中点分割算法直线裁剪&#xff1a;Liang-Barsky 算法多边形裁剪&a…

github主页这样优化,让人眼前一亮

我的主页&#xff08;一之十六&#xff09; 1. 创建与账户ID同名的仓库 注意&#xff1a;记得勾选Add a README file 2. markdown语法自定义README.md 3. 辅助工具 优秀profile&#xff1a;https://zzetao.github.io/awesome-github-profile/动态文字&#xff1a;https://r…

构建高效业财一体化管理体系

构建高效业财一体化管理体系 业财一体化战略意义 提升决策质量 强化数据支撑&#xff1a;通过整合业务与财务数据&#xff0c;为决策提供准确、实时的信息基础&#xff0c;确保分析的深度与广度。促进业务与财务协同&#xff1a;打破信息孤岛&#xff0c;实现业务流程与财务管…

python 压缩数据

requests 是 Python 中一个非常流行的 HTTP 库&#xff0c;用于发送各种 HTTP 请求。下面是一个使用 requests 库发送简单 GET 请求和 POST 请求的示例&#xff1a; 首先&#xff0c;确保你已经安装了 requests 库。如果还没有安装&#xff0c;可以使用 pip 进行安装&#xff…