C语言程序里全局变量、局部变量、堆、栈内存地址分配
C语言程序里全局变量、局部变量、堆、栈内存地址分配
- 1 名词解读
- 2 基于ubuntu编程,调试验证
- 2.1 编写文件
- 2.2 结果分析
- 3 基于stm32编程,调试验证
- 3.1 编写代码
- 3.2 运行结果及分析
1 名词解读
c语言程序中内存通常为4个分区:栈、堆、全局/静态存储区和常量存储区。
- 栈区: 存放函数内的局部变量,形参和函数返回值。栈区之中的数据的作用范围过了之后,系统就会回收自动管理栈区的内存
- 堆区:由程序员调用malloc()函数来主动申请的,需使用free()函数来释放内存,若申请了堆区内存,之后忘记释放内存,很容易造成内存泄漏
- 静态/全局区:静态变量和全局变量的存储区域是一起的,一旦静态区的内存被分配, 静态区的内存直到程序全部结束之后才会被释放
- 常量存储区:存放常量(程序在运行的期间不能够被改变的量。
2 基于ubuntu编程,调试验证
2.1 编写文件
在Ubuntu中新建打开一个 test1.c文件
代码如下:
#include <stdio.h>
#include <stdlib.h>
int k1 = 1;
int k2;
static int k3 = 2;
static int k4;
int main( )
{ static int m1=2, m2;int i = 1;char *p;char str[10] = "hello";char *var1 = "123456";char *var2 = "abcdef";int *p1=malloc(4);int *p2=malloc(4);free(p1);free(p2);printf("栈区-变量地址\n");printf(" i:%p\n", &i);printf(" p:%p\n", &p);printf(" str:%p\n", str);printf("\n堆区-动态申请地址\n");printf(" %p\n", p1);printf(" %p\n", p2);printf("\n.bss段\n");printf("全局外部无初值 k2:%p\n", &k2);printf("静态外部无初值 k4:%p\n", &k4);printf("静态内部无初值 m2:%p\n", &m2);printf("\n.data段\n");printf("全局外部有初值 k1:%p\n", &k1);printf("静态外部有初值 k3:%p\n", &k3);printf("静态内部有初值 m1:%p\n", &m1);printf("\n常量区\n");printf("文字常量地址 :%p\n",var1);printf("文字常量地址 :%p\n",var2);printf("\n代码区\n");printf("程序区地址 :%p\n",&main);return 0;
}
(此处代码参考博客)
按ESC回到命令模式
输入:wq
退出vim编辑器并保存
并且进行编译和运行
命令如下:
gcc test1.c
./a.out
2.2 结果分析
结果如下
根据结果可知
栈的地址是向下增长
堆的地址是向上增长
静态变量是地址向下增长
全局常量是地址向上增长
3 基于stm32编程,调试验证
3.1 编写代码
我们根据正点原子的例程改写
按图示打开文件夹
进去之后选择实验4串口通信文件夹拷贝到自己喜欢的文件夹
之后进去USER文件夹选择kile工程文件打开。
更改主函数如下:
#include "usart.h"
#include "stm32f10x.h"
#include <stdlib.h>char global1[16];
char global2[16];
char global3[16];int main(void)
{ char part1[16];char part2[16];char part3[16];static char st1[16];static char st2[16];static char st3[16];uart_init(115200);printf("part1: 0x%p\r\n", part1);printf("part2: 0x%p\r\n", part2);printf("part3: 0x%p\r\n", part3);printf("global1: 0x%p\r\n", global1);printf("global2: 0x%p\r\n", global2);printf("global3: 0x%p\r\n", global3);printf("st1: 0x%p\r\n", st1);printf("st2: 0x%p\r\n", st2);printf("st3: 0x%p\r\n", st3);while(1){ }
}
3.2 运行结果及分析
烧录过程同我上个博客 “STM32的USART窗口通讯”
结果如下:
part1、part2、part3为栈中的局部变量,地址逐渐减小。
global1、global2、global3为静态区中的全局变量,地址逐渐增加。
st1、st2、st3都是静态变量,地址依次增加。
总结: 通过本次实验,了解了c语言变量在内存地址分配情况,在ubuntu下和stm32上进行对比。对比他们不同环境下的相同点与不同点。
C语言程序里全局变量、局部变量、堆、栈内存地址分配相关推荐
- c# 结构体 4字节对齐_C语言程序员们常说的“内存对齐”,究竟有什么目的?
在C语言程序开发中,有时有经验的程序员会提起"内存对齐"一词,事实上,这也是C语言中结构体的 size 不等于它所有成员 size 之和的原因(C语言中的结构体的size,并不等于 ...
- C语言,函数不可返回指向栈内存的指针
预备知识:内存的分类 C/C++程序占用的内存分为两大类:静态存储区与动态存储区.其示意图如下所示: 数据保存在静态存储区与动态存储区的区别就是:静态存储区在编译-链接阶段已经确定了,程序运行过程中不 ...
- c语言程序的执行过程压栈,汉诺塔---手写出栈压栈过程实现
代码实现: 1 #include 2 3 //函数的形参A.B.C不一定代表的是A.B.C柱子,递归传参的时候会变化! 4 void hanoit(int n,char A,char B,charC) ...
- C语言程序里何时用分号?
分号的使用是初学者往往容易犯错的地方,要么少了分号,要么多了分号.少了分号多见于定义变量和给变量赋值的时候,而多了分号则多见于分支结构和循环结构中.如程序段1.2.3所示. //程序段1,在定义变量和 ...
- c语言程序里 n什么意思,英语中的n是什么意思
介词短语作定语--认识"我"的两种方式,在这一部分要介绍给大家的是作定语的介词短语. (1)何为"介词"及"介词短语" 语法书中对介词的定义 ...
- 如何理解成员变量在堆内,局部变量在栈内?
成员变量在堆内存里,局部变量在栈内存里.(基础类型) 我有疑惑: 既然成员变量存在于对象中,对象存在于堆中,所以成员变量存在于堆中.那么按照这样的推理,局部变量存在于方法中,而方法存在于对象中,对象存 ...
- windows系统-程序加载时生成栈和堆的过程
EXE文件的内容分为再配置信息.变量组和函数组,这一点想必大家都清楚了吧.不过,当程序加载到内存后,除此之外还会额外生成两个组,那就是栈和堆.栈是用来存储函数内部临时使用的变量(局部变量[注1]), ...
- 对C语言 static作用——修饰 变量(全局变量/局部变量)、函数
*******************************概念******************************************** ********************** ...
- c语言程序源代码_程序的编译、链接和执行
同学们总是抱怨每次见到一道面试题都很难把它转化为程序源代码.然而不幸的是,即使是程序源代码对于计算机来说也还是太高级了.要想让计算机执行一段程序,我们必须把它翻译成最底层的机器指令才行.这其中要经历很 ...
最新文章
- 有源汇上下界最小费用可行流 ---- P4043 [AHOI2014/JSOI2014]支线剧情(模板)
- 可怕!公司部署了一个东西,悄悄盯着你···
- 通俗地理解什么是编程语言
- joblib多线程、多进程学习案例(三)
- Oracle用户角色权限管理
- T-SQL语句之创建、修改、删除数据库
- Bailian2716 全局变量【字符流】
- linux tcl是什么系统,基于Linux 及Tcl / Tk 的数控系统人机界面的实现
- Silverlight 2中多语言支持实现(下)
- bzoj3223Tyvj 1729 文艺平衡树 splay
- 木马的检测、清除与防范
- 入职直接给事业编, 90万补贴+50万科启,重庆高校
- HTTP 请求头 Header
- CTEX加中英文摘要
- oracle删sequen,Oracle中如何创建使用SEQUENCES
- 【Python】pass,continue和break的区别
- instance在oracle意思,INSTANCE_NAME的含义及作用
- Android 框架问题分析案例 - 谁杀了桌面?
- 前端面试之html+css【一】
- Angelababy否认已怀身孕:我怎么不知道