避免在C中的结构分配中使用malloc/free Overhead

nik*_*bey 4 c

我正在阅读和试验本书中的指针,

http://shop.oreilly.com/product/0636920028000.do

在本书的第6章中,在避免malloc/free Overhead标题下,作者建议如何在进行大量结构内存分配/解除分配时避免malloc/free开销.

以下是他编写函数的方式,

#define LIST_SIZE 10
Person *list[LIST_SIZE];

void initializeList() 
{
    int i=0;
    for(i=0; i<LIST_SIZE; i++) 
    {
        list[i] = NULL;
    }

}

Person *getPerson() 
{
    int i=0;
    for(i=0; i<LIST_SIZE; i++) 
    {

        if(list[i] != NULL) 
        {
            Person *ptr = list[i];
            list[i] = NULL;
            return ptr;
        }
    }
    Person *person = (Person*)malloc(sizeof(Person));
    return person;
}

void deallocatePerson(Person *person) 
{
    free(person->firstName);
    free(person->lastName);
    free(person->title);
}

Person *returnPerson(Person *person)
{
    int i=0;
    for(i=0; i<LIST_SIZE; i++) 
    {
    if(list[i] == NULL) 
        {
            list[i] = person;
            return person;
        }
    }
    deallocatePerson(person);
    free(person);
    return NULL;
}
Run Code Online (Sandbox Code Playgroud)

我从他的代码中了解到,他创建了一个内存池数组,指向struct person类型,然后用NULL初始化每个数组元素.

接下来,我们将使用getPerson函数从池中获取内存.这个函数检查!= NULL,我认为每次都会失败.所以再次它将是相同的,因为malloc和内存不会随时从池中分配.

  1. 我的理解是否正确?
  2. 这是处理开销的方法吗?
  3. 应该采用哪种正确方法?任何来源/链接将不胜感激.

das*_*ght 7

接下来,我们将使用getPerson函数从池中获取内存.这个函数,!=NULL我认为每次都会失败.

只要您继续getPerson重复呼叫,每次检查都会失败.但是,如果混合使用getPersonreturnPerson,某些NULL检查将成功,因为returnPerson将非NULL值放入数组中.

这种观察对于理解该方法至关重要:该阵列用作struct Person已分配malloc但不再使用的块的小型临时存储.malloc如果有可用的代码,您的代码将从此特殊列表中获取可用块,而不是再次调用.

在您进行数千次分配但LIST_SIZE在任何给定时间永远不会保持活动对象的情况下,malloc呼叫次数限制为LIST_SIZE.

这是处理开销的方法吗?

这是使用旁视列表的一种变体,这是一种非常重要的优化技术,Microsoft创建了一个API用于驱动程序代码.一种更简单的方法将Person *list[LIST_SIZE]用作已释放块的堆栈,即使用最后释放块的索引而不使用循环.

另一种方法是设置这些块的链表,重用块本身的内存来存储next指针.但是,对于介绍性的嘘声,这种技术可能过于复杂.