近期在阅读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