C语言中内存分布及程序运行加载过程

C语言中内存分布及程序运行加载过程,第1张

一个程序内存分配:

下图是APUE中的一个典型C内存空间分布图(虚拟内存)

例如:

int g1=0, g2=0, g3=0

int max(int i)

{

int m1=0,m2,m3=0, p_max

static n1_max=0,n2_max,n3_max=0

p_max = (int )malloc(10)

printf("打印max程序地址\n")

printf("in max: 0xx\n\n",max)

printf("打卜李印max传入参数地灶弊顷址\n")

printf("in max: 0xx\n\n",&i)

printf("打印max函数中静态变量地址\n")

printf("0xx\n",&n1_max)//打印各本地变量的内存地址

printf("0xx\n",&n2_max)

printf("0xx\n\n",&n3_max)

printf("打印max函数中局部变量地址\n")

printf("0xx\n",&m1)//打印各本地变量的内存地址

printf("0xx\n",&m2)

printf("0xx\n\n",&m3)

printf("打印max函数中malloc分配地址\n")

printf("0xx\n\n",p_max)//打印各本地变量的内存地址

if(i) return 1

else return 0

}

int main(int argc, char **argv)

{

static int s1=0, s2, s3=0

int v1=0, v2, v3=0

int p

p = (int )malloc(10)

printf("打印各全局变量(已初始化)的内存地址隐陆\n")

printf("0xx\n",&g1)//打印各全局变量的内存地址

printf("0xx\n",&g2)

printf("0xx\n\n",&g3)

printf("======================\n")

printf("打印程序初始程序main地址\n")

printf("main: 0xx\n\n", main)

printf("打印主参地址\n")

printf("argv: 0xx\n\n",argv)

printf("打印各静态变量的内存地址\n")

printf("0xx\n",&s1)//打印各静态变量的内存地址

printf("0xx\n",&s2)

printf("0xx\n\n",&s3)

printf("打印各局部变量的内存地址\n")

printf("0xx\n",&v1)//打印各本地变量的内存地址

printf("0xx\n",&v2)

printf("0xx\n\n",&v3)

printf("打印malloc分配的堆地址\n")

printf("malloc: 0xx\n\n",p)

printf("======================\n")

max(v1)

printf("======================\n")

printf("打印子函数起始地址\n")

printf("max: 0xx\n\n",max)

return 0

}

打印结果:

ELF目标文件格式的最前端是 ELF****文件头(****ELF Header****)

包含了描述整个文件的基本属性,如ELF版本、目标机器型号、 程序入口地址

3 加载:

如果是集显,执行程序时需要调动集显,有一部分的物理内存会被分配给集显来使用,如果是独显,那就没问题了,独显自己带有内存,不需要共享(部分显卡除外,有些性能强劲的显卡可以分享内存,增加性能),这时候的内存就是你系统所能识别的内存。

从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。

从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。

扩展资料:

C++的内存分配:

根据C++的语法规范,定义数组时数组长度必须用常量而不能用变量表示,此时可以使用动态内存分配解决这一问题。

动态内存分配是指在程序运行时为程序中的变量分配内存空间,它完全由应用程序自己进行内存的分配和回收。

程序运行时好搜散,特别要注意的是内存的分配。有以漏袭下六个地方都可以保存数据。

参考资料来源:百度百科-内存分配友氏

全局变量是在创建对象的时候分配内存的 创建对象过程为

分配空间。

递归的创建父类对象。

初始化成员变量。

调用构造方法创建一个对象。

静态变量是在类加载的时候分配空间的,静态变量和对象没有关系 是在JVM第一次读到一个类的时候加载信息的过程中分配空间的 加载过程为

1 .加载父类(如果父类已经加载过,则不在加载)。

2.初始化静态属性 。

3 .按顺序的初始化静态代码块   初始化的前提就是分配空间 。

而且静态变量在以后的创建对象的扮闭戚时候不在初始化 所以一般用静态来保存共享信息

静态变量存在于方法态丛区中,成员变量存在于堆内存中,成员变量所属于对象JAVA成员变量和静态变量的区别,成员变量随着对象创建而存在。随着对象被回收而消失。静态变量随着类的加载而存在。

静态变量是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量,例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由static加以定义后才能成为静态外部变量,或称静态全局变量。

对于自动变量,它属于动态存储方式。但是也可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式。由此看来,一个变量可由static进行再说明,并改变其原有的存储方式。

而在以Pascal为代表的许多程序语言中,所有局部变量都由系统自动分配存储空间,而所有全局变量的存储空间则以静态分配的方式获取,因此由于实际上“局部变量”和“全局变量”这两个术语已足以涵盖所有的情况,在这些程序语言中通常不使用“静态变量”这一术语,而直接以“全局变量”代之。

在这些程序语言中,静态变量就是全局变量,而即使在有明确区分全局和静态变量的程序语言中,在编译后的代码里二者也以相同的方式获取存储空间。而今术语“静态变量”的概念则主要基于C族语言的“static”的定义。

静态变量也可以用于存储常数。厅陵具体来说,静态变量可用const,constant或final等关键字标识,这时其值就会在编译时设定,并且无法在运行时改变。编译器通常将静态常量与文本一起置于目标文件的文本区域,而非常量初始化数据则置于数据区。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12239972.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-22
下一篇 2023-05-22

发表评论

登录后才能评论

评论列表(0条)

保存