首页天道酬勤常量占存储单元吗,静态变量存储在数据段

常量占存储单元吗,静态变量存储在数据段

张世龙 05-06 03:40 18次浏览

文章目录引言c内存分区如何执行Linux上自由存储体与堆之间的问题堆栈常数分区静态存储体静态局部变量、静态全局变量、全局变量的异同

引言

在动态内存博客中,我说。

在Linux内存管理博客上,我说:

尽管有尽可能完整的描述,两者的大致意思并不矛盾。 我总是觉得有点不同,越看越模糊,原因是第一张图讲的其实是C++在概念上对内存的划分,第二张图讲的是Linux对虚拟内存进行的划分。前者是概念上的,c程序在运行时确实运行,而后者在Linux系统上具象化了前者的概念以下,进一步进行分析。

c内存分区是如何实现在Linux上的?c实际上将内存存储在动态存储区、静态存储区

在第一张图中,—— 堆、栈

在网上的其他博客中,动态存储区可能还分为—— 堆、栈、自由存储区。 针对静态存储区进一步—— 常量存储区、全局/静态存储区。

可以说有很多种,但我们可以先组成一个团体。

自由存储区和堆之间的问题此博客分析了c自由存储区是否等效于堆。 引用其中的几个进行分析:

在概念上我们是这样区分两者的:

malloc分配给堆的内存块使用free释放内存。 new申请的内存位于自由内存上,使用delete释放。 那么物理上,自由存储区与堆是两块不同的内存区域吗?它们有可能相同吗?

基本上,所有c编译器默认使用堆来实现自由存储(缺省全局运算符new和delete )都可能像malloc和free一样实现。 在这种情况下,藉由new运算子指派的物件,http://www.Sina.com/3358www.Sina

说它在堆上也对,说它在自由存储区上也正确。

自由存储是c通过new和delete动态分配和释放对象的但程序员也可以通过重载操作符,改用其他内存来实现自由存储,例如全局变量做的对象池,这时自由存储区就区别于堆了,堆(heap )是c语言和操作系统术语,操作系统

new申请的内存区域在c中称为总结:。 藉由堆实现的自由存储,由new申请的抽象概念

堆与自由存储器区域的动作不同,访问方法不同,因此应该被用作不同的堆。

动态分配内存

c的自由存储区当然对应于Linux的内存区域在堆上,但c的如何落实在Linux上?也不能积极地用其他存储器代替实现自由存储器

如上所述,堆段由程序员申请和释放。

int main () {int *pi=new int; //pi是动态分配的,指向未初始化的无名对象。 该对象的地址位于堆上//中,pi的地址位于main函数的堆栈上。 (在堆栈c的启用自然功能的Linux的3358www.Sina.com/中,堆栈段在每次调用进程运行时(从开始到运行进程时(在主函数中) )的初始函数时显示

void fun () {int j=2; 调用//fun时,j在fun的堆栈帧中显示计数' hello ' endl; }int main ()//创建堆栈段int i=1; //驻留在堆栈段中的fun (; //堆栈帧创建}在常量区域c中,一个const不需要创建存储器区域,而在c中,一个const总是需要一个存储器区域。

堆段

自由存储区

是否为const全局变量分配内存空间取决于此全局常量的用途。 如果用作值替换(用值替换变量名),则不会分配内存空间,但使用此全局常量堆段或extern将分配内存并使用

因为全局变量在内存中的位置与全局常量一样,只不过没有 read only 属性,因此在这里也就一并提了,全局常量同样被分配到数据段上,但是可以修改。

PS:未初始化初始化为0 的全局变量(包括全局常量)被分配在 .bss 段上,已初始化 的被分配在 数据段 上。

局部常量

对于基础数据类型,也就是 const int a = 10 这种,编译器会把它放到符号表中,不分配内存,当对其取地址时,会在栈段分配内存。对于基础数据类型,如果用一个变量初始化 局部常量,如果 const int a = b,那么也是会给 a 在栈段分配内存。对于自定数据类型,比如类对象,那么也会在栈段分配内存。

题外话

c 中 const 默认为外部连接,c++ 中 const 默认为内部连接。当 c 语言两个文件中都有 const int a 的时候,编译器会报重定义的错误。而在 c++ 中则不会,因为 c++ 中的 const 默认是内部连接的。如果想让 c++ 中的 const 具有外部连接,必须显式声明为 extern const int a = 10 。

示例

const int lx = 5;// 没有使用的时候仅保存在符号表// 使用extern或取地址的时候为其在数据段的只读部分分配内存// 个人猜测也有可能在代码段的.rodata。int o = 6;class A{ const int kxdbl = 1; // 在栈段分配内存public: void put() { cout << &kxdbl << endl; }};int main() { A a; int x = 2; // 对照main中的变量来确定其他常量的位置 // 因为我们确定 x 在栈段上 // 因此如果其他常量的地址与 x 的地址类似 // 则说明其他常量也在栈段上 const int z = 1; // 取地址时,会在栈段分配内存 const int y = x; // 取地址时,会在栈段分配内存}

静态存储区

静态变量分为:全局静态变量、局部静态变量

而关于它们的存储位置,我在 Linux内存管理 一文中已经说的很详细了,下面的静态变量包括全局静态变量和局部静态变量:

静态局部变量

猜测下面代码的输出结果:

void f(int) { static int i = 0; cout << &i << " " << ++i << endl;}void f(double) { static int i = 0; cout << &i << " " << ++i << endl;}int main() { f(1); f(1.0); f(1); f(1.0); f(1);}

答案:

这里证明了静态局部变量的特性:只初始化一次,并且只对定义自己的函数可见。 因此在上面的调用中,并不会出现因为两个静态局部变量名字相同而赋值出错的情况。

静态局部变量、静态全局变量、全局变量的异同 全局变量在整个工程文件内都有效,静态全局变量只在定义它的文件内有效;静态局部变量只在定义它的函数内有效,且程序仅分配一次内存(之初始化一次),函数返回后,该变量不会消失;全局变量静态变量如果没有手工初始化,则由编译器初始化为 0 。静态局部变量静态全局变量 共享 数据段(或.BSS段)
java中静态变量存在哪里,一个类在jvm中的存储