使用标准的c malloc
函数很难区分,从我的视角来看,malloc
函数似乎有缺陷。因此,您可以通过实现一些自定义的malloc
函数来管理内存,使用RAM地址。
我不确定这是否对您有所帮助,但我在我的控制器相关项目中完成了一些自定义的malloc
函数,如下所示:
#define LENGTH_36_NUM (44)
#define LENGTH_52_NUM (26)
#define LENGTH_64_NUM (4)
#define LENGTH_128_NUM (5)
#define LENGTH_132_NUM (8)
#define LENGTH_256_NUM (8)
#define LENGTH_512_NUM (18)
#define LENGTH_640_NUM (8)
#define LENGTH_1536_NUM (6)
#define CUS_MEM_USED (1)
#define CUS_MEM_NO_USED (0)
#define CALC_CNT (0)
#define CALC_MAX (1)
#define __Ram_Loc__ (0x20000000)
#define __TOP_Ram_Loc__ (0x20000000 + 0x8000 -0x10)
typedef struct _CUS_MEM_BLOCK_S {
char used;
int block_size;
char *ptr;
char *next;
} cus_mem_block_s;
static struct _MEM_INFO_TBL_S {
int block_size;
int num_max;
cus_mem_block_s *wm_head;
int calc[2];
} memInfoTbl[] = {
{36, LENGTH_36_NUM , 0, {0,0} },
{52, LENGTH_52_NUM , 0, {0,0} },
{64, LENGTH_64_NUM , 0, {0,0} },
{128, LENGTH_128_NUM , 0, {0,0} },
{132, LENGTH_132_NUM , 0, {0,0} },
{256, LENGTH_256_NUM , 0, {0,0} },
{512, LENGTH_512_NUM , 0, {0,0} },
{640, LENGTH_640_NUM , 0, {0,0} },
{1536,LENGTH_1536_NUM, 0, {0,0} },
};
#define MEM_TBL_MAX (sizeof(memInfoTbl)/sizeof(struct _MEM_INFO_TBL_S))
BOOL MemHeapHasBeenInitialised = FALSE;
这基本上是为RAM地址定义的宏,并手动选择更多的块数来适应频繁需要分配的块大小,例如我需要36个字节,因此我选用了更多的块数。
这是mem init的初始化函数。
void cus_MemInit(void)
{
int i,j;
cus_mem_block_s *head=NULL;
unsigned int addr;
addr = __Ram_Loc__;
for(i=0; i<MEM_TBL_MAX; i++)
{
head = (char *)addr;
memInfoTbl[i].wm_head = head;
for(j=0;j<memInfoTbl[i].num_max; j++)
{
head->used =CUS_MEM_NO_USED;
head->block_size = memInfoTbl[i].block_size;
head->ptr = (char *)(addr + sizeof(cus_mem_block_s));
addr += (memInfoTbl[i].block_size + sizeof(cus_mem_block_s));
head->next =(char *)addr;
head = head->next;
if(head > __TOP_Ram_Loc__)
{
printf("%s:error.\n",__FUNCTION__);
return;
}
}
}
head->ptr = 0;
head->block_size = 0;
head->next = __Ram_Loc__;
MemHeapHasBeenInitialised=TRUE;
}
这是一篇关于分配的内容。
void* CUS_Malloc( int wantedSize )
{
void *pwtReturn = NULL;
int i;
cus_mem_block_s *head;
if(MemHeapHasBeenInitialised == FALSE)
goto done_exit;
for(i=0; i<MEM_TBL_MAX; i++)
{
if(wantedSize <= memInfoTbl[i].block_size)
{
head = memInfoTbl[i].wm_head;
while(head->ptr)
{
if(head->used == CUS_MEM_NO_USED)
{
head->used = CUS_MEM_USED;
pwtReturn = head->ptr;
goto done;
}
head = head->next;
}
goto done;
}
}
done:
if(pwtReturn)
{
for(i=0; i<MEM_TBL_MAX; i++)
{
if(memInfoTbl[i].block_size == head->block_size)
{
memInfoTbl[i].calc[CALC_CNT]++;
if(memInfoTbl[i].calc[CALC_CNT] > memInfoTbl[i].calc[CALC_MAX] )
memInfoTbl[i].calc[CALC_MAX]=memInfoTbl[i].calc[CALC_CNT];
break;
}
}
}
done_exit:
return pwtReturn;
}
这是免费的。
这里是需要翻译的内容。
void CUS_Free(void *pm)
{
cus_mem_block_s *head;
char fault=0;
if( (pm == NULL) || (MemHeapHasBeenInitialised == FALSE) )
goto done;
if( (pm < __RamAHB32__) && (pm > __TOP_Ram_Loc__) )
{
printf("%s:over memory range\n",__FUNCTION__);
goto done;
}
head = pm-sizeof(cus_mem_block_s);
if(head->used)
head->used = CUS_MEM_NO_USED;
else
{
printf("%s:free error\n",__FUNCTION__);
fault=1;
}
if(fault)
goto done;
int i;
for(i=0;i<MEM_TBL_MAX;i++)
{
if(memInfoTbl[i].block_size == head->block_size)
{
memInfoTbl[i].calc[CALC_CNT]--;
goto done;
}
}
done:;
}
最终,您可以像这样使用上述函数:
void *mem=NULL;
mem=CUS_Malloc(wantedsize);
然后您也可以按以下方式查看已使用的内存。
void CUS_MemShow(void)
{
int i;
int block_size;
int block_cnt[MEM_TBL_MAX];
int usedSize=0, totalSize=0;
cus_mem_block_s *head;
if(MemHeapHasBeenInitialised == FALSE)
return;
memset(block_cnt, 0, sizeof(block_cnt));
head = memInfoTbl[0].wm_head;
i=0;
block_size = head->block_size;
vTaskSuspendAll();
while( head->ptr !=0)
{
if(head->used == CUS_MEM_USED )
{
block_cnt[i]++;
usedSize +=head->block_size;
}
usedSize += sizeof(cus_mem_block_s);
totalSize += (head->block_size+ sizeof(cus_mem_block_s));
head = head->next;
if( block_size != head->block_size)
{
block_size = head->block_size;
i++;
}
}
xTaskResumeAll();
usedSize += sizeof(cus_mem_block_s);
totalSize+= sizeof(cus_mem_block_s);
dprintf("----Memory Information----\n");
for(i=0; i<MEM_TBL_MAX; i++) {
printf("block %d used=%d/%d (max %d)\n",
memInfoTbl[i].block_size, block_cnt[i],
memInfoTbl[i].num_max,
memInfoTbl[i].calc[CALC_MAX]);
}
printf("used memory=%d\n",usedSize);
printf("free memory=%d\n",totalSize-usedSize);
printf("total memory=%d\n",totalSize);
printf("--------------------------\n");
}
一般来说,先预估所需内存,然后按照预估值提供。
curr = (item *)malloc(sizeof(item));
后添加了你的代码 - 结果:程序不再在第18次循环分配内存时崩溃,而是在第17次循环的memset()
行崩溃。 - Boernmalloc
,以查看哪一行导致调用硬错误处理程序。您可以使用带有不同C库实现的GCC,因此说您使用GCC并不能真正说明您使用哪个C库实现。我们只能假设您使用默认的C库实现。 - Étienne