创建链表的一种方式

近期在阅读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*的内存(注:指针所占用的空间取决于机器字长)

第二点是这里的一种创建链表的方式,具体理解见下图

创建链表的一种方式

上一篇:Oracle 非常规恢复之二dul恢复truncate表


下一篇:理解ls -F1