这个问题的灵感来自
我编写了一个程序,该程序通过调用为链表中的各个节点分配内存malloc。
有一些速度测试,其中malloc包含一个函数,该函数导致malloc调用花费比正常时间更多的时间。这使测试能够检测到malloc的频繁使用。
如何避免呼叫malloc每个节点?
在速度测试中,包装函数调用了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)