C语言程序里全局变量、局部变量、堆、栈内存地址分配

C语言程序里全局变量、局部变量、堆、栈内存地址分配

  • 1 名词解读
  • 2 基于ubuntu编程,调试验证
    • 2.1 编写文件
    • 2.2 结果分析
  • 3 基于stm32编程,调试验证
    • 3.1 编写代码
    • 3.2 运行结果及分析

1 名词解读

c语言程序中内存通常为4个分区:栈、堆、全局/静态存储区和常量存储区。

  1. 栈区: 存放函数内的局部变量,形参和函数返回值。栈区之中的数据的作用范围过了之后,系统就会回收自动管理栈区的内存
  2. 堆区:由程序员调用malloc()函数来主动申请的,需使用free()函数来释放内存,若申请了堆区内存,之后忘记释放内存,很容易造成内存泄漏
  3. 静态/全局区:静态变量和全局变量的存储区域是一起的,一旦静态区的内存被分配, 静态区的内存直到程序全部结束之后才会被释放
  4. 常量存储区:存放常量(程序在运行的期间不能够被改变的量。

2 基于ubuntu编程,调试验证

2.1 编写文件

在Ubuntu中新建打开一个 test1.c文件
代码如下:

#include 
#include 
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 结果分析

结果如下
C语言程序里全局变量、局部变量、堆、栈内存地址分配_第1张图片
根据结果可知
栈的地址是向下增长
堆的地址是向上增长
静态变量是地址向下增长
全局常量是地址向上增长

3 基于stm32编程,调试验证

3.1 编写代码

我们根据正点原子的例程改写
按图示打开文件夹C语言程序里全局变量、局部变量、堆、栈内存地址分配_第2张图片
C语言程序里全局变量、局部变量、堆、栈内存地址分配_第3张图片
进去之后选择实验4串口通信文件夹拷贝到自己喜欢的文件夹
之后进去USER文件夹选择kile工程文件打开。
更改主函数如下:

#include "usart.h"
#include "stm32f10x.h"
#include 

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窗口通讯”
结果如下:
C语言程序里全局变量、局部变量、堆、栈内存地址分配_第4张图片

part1、part2、part3为栈中的局部变量,地址逐渐减小。
global1、global2、global3为静态区中的全局变量,地址逐渐增加。
st1、st2、st3都是静态变量,地址依次增加。
总结: 通过本次实验,了解了c语言变量在内存地址分配情况,在ubuntu下和stm32上进行对比。对比他们不同环境下的相同点与不同点。

你可能感兴趣的:(c语言)