提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
用c程序实现在Ubuntu和是stm32观察内存分配问题- C语言内存分配
- 一、Ubuntu和stm32下测试
- 1、Ubuntu
- 2.stm32
- 总结
- 参考文献
C语言内存分配
在C语言中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
- 栈
就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。
- 堆
就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
- 自由存储区
就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
- 全局/静态存储区
全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C 里面没有这个区分了,他们共同占用同一块内存区。
- 常量存储区
这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。
一、Ubuntu和stm32下测试代码如下:
#include1、Ubuntu#include //定义全局变量 int init_global_a = 1; int uninit_global_a; static int inits_global_b = 2; static int uninits_global_b; void output(int a) { printf("hello"); printf("%d",a); printf("n"); } int main( ) { //定义局部变量 int a=2; static int inits_local_c=2, uninits_local_c; int init_local_d = 1; output(a); char *p; char str[10] = "lyy"; //定义常量字符串 char *var1 = "1234567890"; char *var2 = "qwertyuiop"; //动态分配 int *p1=malloc(4); int *p2=malloc(4); //释放 free(p1); free(p2); printf("栈区-变量地址n"); printf(" a:%pn", &a); printf(" init_local_d:%pn", &init_local_d); printf(" p:%pn", &p); printf(" str:%pn", str); printf("n堆区-动态申请地址n"); printf(" %pn", p1); printf(" %pn", p2); printf("n全局区-全局变量和静态变量n"); printf("n.bss段n"); printf("全局外部无初值 uninit_global_a:%pn", &uninit_global_a); printf("静态外部无初值 uninits_global_b:%pn", &uninits_global_b); printf("静态内部无初值 uninits_local_c:%pn", &uninits_local_c); printf("n.data段n"); printf("全局外部有初值 init_global_a:%pn", &init_global_a); printf("静态外部有初值 inits_global_b:%pn", &inits_global_b); printf("静态内部有初值 inits_local_c:%pn", &inits_local_c); printf("n文字常量区n"); printf("文字常量地址 :%pn",var1); printf("文字常量地址 :%pn",var2); printf("n代码区n"); printf("程序区地址 :%pn",&main); printf("函数地址 :%pn",&output); return 0; }
程序自取
链接: https://pan.baidu.com/s/1WdU5KsOYfY4g3IP3pgtmFQ
提取码: t2k9
利用之前的BH_103工程
- 在 bsp_usart.h 文件中添加头文件代码
代码如下:
#include#include
- 在 bsp_usart.c 文件中重写 fputc 函数
int fputc(int ch, FILE *f)
{
USART_SendData(DEBUG_USARTx, (uint8_t)ch);
while(USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
return (ch);
}
- main.c 文件修改为下面的代码
#include "stm32f10x.h"
#include "bsp_usart.h" //添加 bsp_usart.h 头文件
int init_global_a = 1;
int uninit_global_a;
static int inits_global_b = 2;
static int uninits_global_b;
void output(int a)
{
printf("hello");
printf("%d",a);
printf("n");
}
int main(void)
{
//定义局部变量
int a=2;
static int inits_local_c=2, uninits_local_c;
int init_local_d = 1;
char *p;
char str[10] = "lyy";
//定义常量字符串
char *var1 = "1234567890";
char *var2 = "qwertyuiop";
//动态分配
int *p1=malloc(4);
int *p2=malloc(4);
USART_Config();//串口初始化
output(a);
//释放
free(p1);
free(p2);
printf("栈区-变量地址n");
printf(" a:%pn", &a);
printf(" init_local_d:%pn", &init_local_d);
printf(" p:%pn", &p);
printf(" str:%pn", str);
printf("n堆区-动态申请地址n");
printf(" %pn", p1);
printf(" %pn", p2);
printf("n全局区-全局变量和静态变量n");
printf("n.bss段n");
printf("全局外部无初值 uninit_global_a:%pn", &uninit_global_a);
printf("静态外部无初值 uninits_global_b:%pn", &uninits_global_b);
printf("静态内部无初值 uninits_local_c:%pn", &uninits_local_c);
printf("n.data段n");
printf("全局外部有初值 init_global_a:%pn", &init_global_a);
printf("静态外部有初值 inits_global_b:%pn", &inits_global_b);
printf("静态内部有初值 inits_local_c:%pn", &inits_local_c);
printf("n文字常量区n");
printf("文字常量地址 :%pn",var1);
printf("文字常量地址 :%pn",var2);
printf("n代码区n");
printf("程序区地址 :%pn",&main);
printf("函数地址 :%pn",&output);
return 0;
}
- 编译烧录
总结
stm32板一定要先BOOT0先置1烧录,然后拔了电,置0,再连接电脑上,再按复位键就可以了。
参考文献C程序在 Ubuntu 和 STM32 中内存分区【全局变量、局部变量、堆、栈】
基于ubuntu,树莓派和stm32的C程序的内存分配问题



