C语言的内存模型

1.运行之前:
预处理:宏定义 头文件展开 条件编译  不会检查语法
编译: 检查语法,将预处理后的文件编译成汇编文件
汇编:将汇编文件生成目标文件 (二进制文件)
链接: 将目标链接成可执行文件。

没有运行程序栈,也就是说程序还没有加载到内存前,可执行程序(size + 可执行程序),可执行程序
内部已经分为三段信息,分别为代码区(text) 数据区(data)   未初始化数据区(bss)三个区域。

2.
data:静态数据和全局初始化变量

码区:只读,共享 

数据区:包含了程序中明确被初始化的全局变量 已经初始化的静态变量(包括全局静态变量和局部静态变量),和常量数据(如字符串常量)

bss区:存入的是全局未初始化变量 和未初始化静态变量,程序楷书之前全局初始化为0 

源代码被编译之后,主要分为两个段,程序指令和程序数据,代码段数据程序指令,而数据段和bss段属于程序数据。

运行之后,堆和栈两个区就出现了,

堆区,是我们程序员自己开辟的区域 ,自己管理的区域。
栈区,是编译器为我们自动开辟,编译器自动管理的区域。内存大小是固定的,

全局静态区: 全局变量(全局区) 静态变量(静态区)  常量(常量区)。

全局区: 默认外部链接
静态区: 默认内部链接 
常量区: 字符串常量 "hello world" ,const修饰的全局变量 ,常量区数据一旦初始化,不能修改,只读内存。

bss: 未初始化数据区。(未初始化的全局变量或者静态局部变量)
因为data区和bss区是一直存在的,所以事先创建好,省事。

3.

代码区:只读,共享 

数据区:包含了程序中明确被初始化的全局变量 已经初始化的静态变量(包括全局静态变量和局部静态变量),和常量数据(如字符串常量)

bss区:存入的是全局未初始化变量 和未初始化静态变量,程序楷书之前全局初始化为0 

源代码被编译之后,主要分为两个段,程序指令和程序数据,代码段数据程序指令,而数据段和bss段属于程序数据。

运行之后,堆和栈两个区就出现了,

堆区,是我们程序员自己开辟的区域 ,自己管理的区域。
栈区,是编译器为我们自动开辟,编译器自动管理的区域。内存大小是固定的,

全局静态区: 全局变量(全局区) 静态变量(静态区)  常量(常量区)。

全局区: 默认外部链接
静态区: 默认内部链接 
常量区: 字符串常量 "hello world" ,const修饰的全局变量 ,常量区数据一旦初始化,不能修改,只读内存。

栈 先进后出,
堆申请没有释放 容易造成内存泄漏。

运行之后才会有栈 和堆在程序运行之后才会有。

运行之后:才会出现堆和栈

ANSI C规定: 修改字符串常量,结果是未定的,所以有些编译器可以修噶字符串常量,有些不可以。

1.有些编译器可以修改字符串常量,有些编译器不可以修改;
2.有些编译器把多个相同的字符串常量看成一个(这种优化可能出现在字符串常量中,节省空间,有些不进行优化,如果进行优化,则可能导致修改一个字符串常量导致另外的字符串常量也发生变化,结果未知)
所以尽量不要去修改字符串常量。

函数调用流程:
    没有栈就没有函数,栈是一种规则,先进后出,栈是有底的,像个杯子,先进后出,压栈的操作以及栈顶 栈底 ,栈的大小是固定的,
    栈总是向下增长的,压栈使得栈顶的地址变小,出栈使得栈顶地址增大,栈对于函数很重要:
    1.函数的返回地址
    2.函数的参数
    3.临时变量
    4.保存的上下文,包括在函数调用前后需要保持不变的寄存器。

main函数开辟的栈内存和堆内存,只要没有被释放,子函数都是可以使用的。
因为这些内存还没有被释放。所以子函数开辟的局部变量是在栈上,所以主函数是不可以使用的,但是子函数如果开辟的是堆内存,并且没有被free掉,那么主函数也是可以使用的。

内存方向,栈底是高地址,所以栈是开口向下的,一直压栈的话,内存地址是越来越低的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值