近期在阅读berkeley-abc源码时,学习了一种新的创建链表的方式,特此记录
源代码:
char *Aig_MmFixedEntryFetch(Aig_MmFixed_t *p)
{
char *pTemp;
int i;
// check if there are still free entries
if (p->nEntriesUsed == p->nEntriesAlloc)
{ // need to allocate more entries
assert(p->pEntriesFree == NULL);
if (p->nChunks == p->nChunksAlloc)
{
p->nChunksAlloc *= 2;
p->pChunks = ABC_REALLOC(char *, p->pChunks, p->nChunksAlloc);
}
p->pEntriesFree = ABC_ALLOC(char, p->nEntrySize * p->nChunkSize);
p->nMemoryAlloc += p->nEntrySize * p->nChunkSize;
// transform these entries into a linked list
pTemp = p->pEntriesFree;
for (i = 1; i < p->nChunkSize; i++)
{
*((char **)pTemp) = pTemp + p->nEntrySize;
pTemp += p->nEntrySize;
}
// set the last link
*((char **)pTemp) = NULL;
// add the chunk to the chunk storage
p->pChunks[p->nChunks++] = p->pEntriesFree;
// add to the number of entries allocated
p->nEntriesAlloc += p->nChunkSize;
}
// incrememt the counter of used entries
p->nEntriesUsed++;
if (p->nEntriesMax < p->nEntriesUsed)
p->nEntriesMax = p->nEntriesUsed;
// return the first entry in the free entry list
pTemp = p->pEntriesFree;
p->pEntriesFree = *((char **)pTemp);
return pTemp;
}
其中一段是创建链表的代码
for (i = 1; i < p->nChunkSize; i++)
{
*((char **)pTemp) = pTemp + p->nEntrySize;
pTemp += p->nEntrySize;
}
// set the last link
*((char **)pTemp) = NULL;
这里学习到了三点
第一点是对地址保存的数据进行灵活操作,pTemp原本是char*类型的指针,也就是说编译器遇到*pTemp,根据指针类型从指针指向的地址向后寻址存储一个字符的内存,这里使用(char**)pTemp对指针pTemp的类型进行强制类型转换为char**类型,也就是说(char**)pTemp指针指向的地址存储char*类型的指针,*(char**)pTemp从pTemp指向的地址向后寻址存储一个char*的内存(注:指针所占用的空间取决于机器字长)
第二点是这里的一种创建链表的方式,具体理解见下图,一个简单的demo见“https://github.com/2994186010/cplusplus/tree/master”中的linklist.cpp

第三点,指向某个数据块的指针加1,该指针地址值的增量=该数据块的字节数,一个简单的demo见“https://github.com/2994186010/cplusplus/tree/master”中的testPointer.cpp
这篇博客记录了在阅读berkeley-abc源码时学到的一种创新链表创建方式。通过动态分配内存并利用指针转换,将内存块转化为链表节点。在内存不足时,源码会自动扩展内存并构建链表。这个过程涉及到指针的强制类型转换,链表节点的链接以及内存管理。此外,博客还强调了指针加法操作在处理数据块时的重要性。
3857

被折叠的 条评论
为什么被折叠?



