stm32 使用malloc申请内存和free释放内存造成的内存碎片测试

来源:互联网 发布:nginx 在线人数统计 编辑:程序博客网 时间:2024/05/20 10:15

本例中使用stm32c8t6  mdk3.5 和 gcc-arm-none-eabi-4_9。使用EmBitz IDE  ARM GCC Compiler。

单片机是不建议使用 内存管理函数,但是在物联网应用当中,内存资源很是宝贵,MQTT 协议需要SSL TLS,数据签名 MD5,RSA等等 使用很是耗费内存资源,

使用内存管理函数就显得很有必要了。

经过测试不断的malloc和free 堆还是比较稳定的,测试 的基本思想是

随机小内存申请->如果大内存申请就释放->随机大内存申请->释放申请的小内存  这样一直循环,循环超过了一万次,堆内存稳定在0x200045d0这个地方



100个 范围在1byte-100bye的随机 内存申请和释放,和10 个 范围在10byte-1000byte的随机内存的申请和释放。

在不断的申请释放中堆内存会产生碎片,堆内存不够的的话就好调用_sbrk函数 increment 增加堆内存空间,如过稳定的话就不会增加堆内存空间,这样就是安全的。

不会一直增长到和栈内存空间重叠,堆内存空间和堆内存空间重叠是会导致不可预料的错误结果。

示例代码:

#include "stm32f10x_conf.h"#include <stdio.h>#include <string.h>#include <stdlib.h>//char myRWdata[]={0,2,3,4};//char myRIData[10];#define MEM_SIZE 100#define BIG_MEM_SIZE 10void serial_init(){    GPIO_InitTypeDef GPIO_InitStruct;    USART_InitTypeDef USART_InitStruct;    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2;    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;    GPIO_Init(GPIOA,&GPIO_InitStruct);    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3;    GPIO_Init(GPIOA,&GPIO_InitStruct);    USART_InitStruct.USART_BaudRate=9600;    USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;    USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;    USART_InitStruct.USART_Parity=USART_Parity_No;    USART_InitStruct.USART_StopBits=USART_StopBits_1;    USART_InitStruct.USART_WordLength=USART_WordLength_8b;    USART_Init(USART2,&USART_InitStruct);    USART_Cmd(USART2,ENABLE);}  int _write (int fd, char *pBuffer, int size) //重定向打印函数printf的输出到USART2     {        for (int i = 0; i < size; i++)        {            while (!(USART2->SR & USART_SR_TXE))            {            }            USART_SendData(USART2, pBuffer[i]);        }        return size;    }     caddr_t _sbrk(int increment)     {        extern char end asm("end");        register char *pStack asm("sp");        static char *s_pHeapEnd;        if (!s_pHeapEnd)            s_pHeapEnd = &end;        if (s_pHeapEnd + increment > pStack)            return (caddr_t)-1;        char *pOldHeapEnd = s_pHeapEnd;        s_pHeapEnd += increment;        return (caddr_t)pOldHeapEnd;    }void test_mem(){    char *mem_list[MEM_SIZE];    memset(mem_list,0,sizeof(char *)* MEM_SIZE);      for(int i=0;i<MEM_SIZE;i++)      {          int r =1+(int)(100.0*rand()/(RAND_MAX+1.0));          //printf("size =%d\r\n",r);          mem_list[i]=(char *)malloc(r);      }    for(int i=0;i<MEM_SIZE;i++)      {        char *p= mem_list[i];        if (p!=NULL)        {             //printf("free mem i=%d\r\n",i);            free(p);            mem_list[i]=NULL;        }    }}int main(void){    serial_init();//串口初始化        GPIO_InitTypeDef GPIO_InitStruct;   //led灯初始化    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;    GPIO_Init(GPIOB,&GPIO_InitStruct);char *mem_list[MEM_SIZE];memset(mem_list,0,sizeof(char *)* MEM_SIZE);char *mem_big[BIG_MEM_SIZE];memset(mem_big,0,sizeof(char *)* BIG_MEM_SIZE);  while(1)  {            GPIOB->ODR = 0xffffffff; //点亮led灯,判断程序是否在运行      for(int i=0;i<1000000;i++);       GPIOB->ODR=00; //熄灭led灯,判断程序是否在运行             if(n>10000) n=0;  //循环10000次归零      n++;      //printf("count=%d\r\n",n);      srand(n);      for(int i=0;i<MEM_SIZE;i++)      {          int r =1+(int)(100.0*rand()/(RAND_MAX+1.0));  //产生1-100 随机数          //printf("size =%d\r\n",r);          mem_list[i]=(char *)malloc(r);   //申请100个 范围在1byte-100bye的随机大小内存      }       for(int i=0;i<BIG_MEM_SIZE;i++)          {        char *p= mem_big[i];        if (p!=NULL)        {            // printf("free mem1 i=%d\r\n",i);            free(p);                      //释放10byte-1000bye随机大小内存            mem_big[i]=NULL;        }      }      test_mem(); //100个 范围在1byte-100bye的随机大小内存申请然后释放      test_mem();//100个 范围在1byte-100bye的随机大小内存申请然后释放      test_mem();//100个 范围在1byte-100bye的随机大小内存申请然后释放      test_mem();//100个 范围在1byte-100bye的随机大小内存申请然后释放        for(int i=0;i<BIG_MEM_SIZE;i++)      {          int r =1+(int)(100.0*rand()/(RAND_MAX+1.0));   //产生1-100 随机数          //printf("size =%d\r\n",r);          mem_big[i]=(char *)malloc(r*10);   //申请10个范围在10byte-1000bye的随机大小内存      }    for(int i=0;i<MEM_SIZE;i++)      {        char *p= mem_list[i];        if (p!=NULL)        {             //printf("free mem i=%d\r\n",i);            free(p);               //释放1byte-100bye随机大小内存            mem_list[i]=NULL;        }    }  }}




0 0
原创粉丝点击