Realloc()即使经过大量阅读后也无法理解

时间:2015-05-19 14:10:42

标签: c memory embedded

我正在编写一个简单的任务调度程序,并在具有4kB RAM的德州仪器cc430F5137上使用动态内存分配。我同意这不是一个好习惯,但暂时让我们假设使用动态内存分配是我的应用程序要求。

在我的OS.c文件中

我有两个结构,

typedef struct
{
    task_t task;
    uint8_t next;
    uint8_t prev;
    uint8_t priority;

} info_t;


typedef struct
{
    task_t task;
    uint8_t index;
} index_t;

info_t的大小为8个字节,index_t的大小为6个字节。

我也是

index_t* m_index;
info_t* m_info;

然后我初始化了我做的功能

m_info = NULL;
m_index = NULL;

现在我有一个函数registerTask(& task),它接受​​要调度的函数的地址。在这个函数中我做

m_info = (info_t*)realloc(m_info,(num_registered_tasks + 1) * sizeof(info_t));

然后设置.priority,next,task和prev。

的值

然后我做

m_index = (index_t*)realloc(m_index,(num_registered_tasks + 1) * sizeof(index_t));

并设置任务和索引的值。  并做num_registered_tasks++;

我的问题是realloc()在这方面的表现如何。

假设我的记忆空间, 第一个任务已注册,因此m_info[0]的前8个字节和m_index[0]的后6个字节。 现在,当我的第二个任务调用此函数时,会发生什么?我猜测的是,对于m_info,它将首先查找16个字节的连续数据,并且只会在前14个字节之后找到它,它将更改m_info[0]的地址并复制内容然后添加{{1 }}。当调用m_info[1]时,它只会在此(14 + 16)字节后找到12个字节,并在此处放置m_indexm_index[0]

请看一下图片 [IMG] http://i.imgur.com/iJnOG2T.jpg[/img]

我如何利用之前的空间?

我需要m_index[1]结构来实现某种搜索算法,所以它也是必要的

2 个答案:

答案 0 :(得分:2)

  

如果这是真的那么我之前的所有空间都被浪费了?

没有;如果realloc() 移动而不是扩展分配,则先前的分配将被释放回堆中,并可供后续分配使用。

你无疑会做的是导致块的碎片化,增加分配失败的变化,并且经历广泛不同的分配时间。

如果必须使用realloc(),则应该使用一种算法,通过一次分配多个块来降低块移动的频率。例如,当需要初始分配时,而不是分配一个块分配16;后续任务可以使用16个预分配块中的一个(确定性地)。当这些用尽时,再分配16个而不是一个。或者,您可以使用几何级数,例如从4个块开始,然后从8,16,32开始,或许达到某个最大值,以便此后增量固定为32.这将减少碎片以及必须分配和移动数据的变化。

答案 1 :(得分:0)

经过大量的不使用动态内存的评论和答案后,我仍然找到了解决问题的方法。

我在我的代码中更改了这个

typedef struct
{
    task_t task;
    uint8_t next;
    uint8_t prev;
    uint8_t priority;

} info_t;


typedef struct
{
    task_t task;
    uint8_t index;
} index_t;

typedef struct
{
    info_t m_info;
    info_t m_index;
} combined_t;

combined_t* m_combined;

通过这个,我的realloc()为m_combined分配了连续的内存,我的碎片问题得到了解决。 (我猜是因为在逐步分析记忆后)。