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又做了一篇文章,算是对大家的一种分享,也是对自己学习的一些总结,文章难免有不妥之处,有老铁们看出,还望不吝赐教。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值