如何避免为链表中的每个节点调用malloc

Dav*_*len 1 c linux malloc

这个问题的灵感来自

防止malloc函数包装

我编写了一个程序,该程序通过调用为链表中的各个节点分配内存malloc

有一些速度测试,其中malloc包含一个函数,该函数导致malloc调用花费比正常时间更多的时间。这使测试能够检测到malloc的频繁使用。

如何避免呼叫malloc每个节点?

Bre*_*dan 6

在速度测试中,包装函数调用了malloc,编写该包装函数会占用更多时间并分配内存。因此,每当我在图表中调用malloc时,都会调用它,但它会花费更多时间,因此测试可以检测到malloc的使用情况。问题是我使用链接列表,因此内存是为列表的每个节点分别分配的。我不知道如何更改此实现,因为在我的结构中使用链接列表确实很舒服。

您也许可以改用数组。

举个简单的例子:

#include <stdio.h>
#include <stdlib.h>

struct list_entry {
    struct list_entry *next;
    int foo;
};

#define MAX_THINGS 1234567
struct list_entry myArray[MAX_THINGS];
int firstFreeEntry = 0;

struct list_entry *freeListHead = NULL;

struct list_entry *listHead = NULL;

struct list_entry *allocEntry(void) {
    struct list_entry *temp;

    if(freeListHead != NULL) {
        // Recycle a previously freed entry
        temp = freeListHead;
        freeListHead = temp->next;
        return temp;
    }
    // Try to take a new entry from the array
    if(firstFreeEntry < MAX_THINGS) {
        return &myArray[firstFreeEntry++];
    }
    // Give up (no free entries)
    return NULL;
}

void freeEntry(struct list_entry *entry) {
    int offset;

    // Try to give it back to the array
    offset = entry - myArray;
    if(offset == firstFreeEntry - 1) {
        firstFreeEntry--;
        return;
    }
    // Put it on the list of freed things
    entry->next = freeListHead;
    freeListHead = entry;
}

// Allocate an entry, initialize/construct it, and put it on the linked list

struct list_entry *createEntry(int value) {
    struct list_entry *newEntry;
    newEntry = allocEntry();
    if(newEntry != NULL) {
        newEntry->foo = value;
        newEntry->next = listHead;
        listHead = newEntry;
    }
    return newEntry;
}

int main() {
    const int node_count = 1000 * 1000;
    struct list_entry *head = NULL;
    for (int index = 0; index < node_count; index++) {
        head = createEntry(0xdeadbeef);
        printf("address of head = %p\n", head);
    }
    while (head) {
        struct list_entry *next = head->next;
        printf("address of head = %p\n", head);
        freeEntry(head);
        head = next;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出量

address of head = 0x101d32040
address of head = 0x101d32050
address of head = 0x101d32060
...
address of head = 0x101d32040
Run Code Online (Sandbox Code Playgroud)

验证

$ ./test > storage.txt
$ split -l 1000000 storage.txt
$ tac xab > xac
$ diff xaa xac
Run Code Online (Sandbox Code Playgroud)