“是什么意思?”*((char**)pTemp)=pTemp+;2;&引用;

“是什么意思?”*((char**)pTemp)=pTemp+;2;&引用;,c,C,我正在阅读的源代码。下面是一个代码片段 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

我正在阅读的源代码。下面是一个代码片段

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;
}
#include <stdio.h>
int main() {
  char* pTemp = "aaaaaaaaaa";
  printf("%s 1\n", pTemp);
  *((char**)pTemp) = pTemp+2;
  printf("%s 2\n", pTemp);
  return 0;
}
aaaaaaaaaa 1
zsh: segmentation fault (core dumped)
*((char**)pTemp)=pTemp+p->nEntrySize
表示将
p->nEntrySize
字节数超过
pTemp
的地址放入位于
pTemp
char*

pTemp
指向一些被组织成若干“条目”的内存。该代码通过在指向下一个条目的每个条目的开头放置一个指针(a
char*
)将其放入一个链表中

给定指向当前条目的指针
pTemp
,且条目大小为
p->nEntrySize
字节,
pTemp+p->nEntrySize
是下一个条目的地址。然后
(char**)pTemp
char*
pTemp
转换为
char**
,一个指向
char*
的指针。因此,赋值表示“将为
pTemp+p->nEntrySize
计算的地址放在
pTemp
指向的地址


这与
pTemp+=p->nEntrySize;
不同,后者表示更改
pTemp
,而不是更改
pTemp
指向的内存。

为什么不
*pTemp=pTemp+…

我不想批评代码,但这种演员阵容
(char**)
和裸体地址方法似乎有点……创造性

使用稍微不同的概念,这可以更干净地完成。我没有指向字节(char)的指针,而是指向地址(void)的指针。还有一个间接寻址,但没有伪基本类型(
void*
而不是
char
(无星)):


<> > <代码> char ** /代码>我得到关于 char */COD>的编译器警告,它有<代码> char **/COD>赋值(在<代码> *Currp= )。< /P>这是真正的C代码,不是C++。C++中只是未定义的。Behavior@AndrewTruckle,它们对应的代码段是“((char**)pTemp)=pTemp+p->nEntrySize;”,他们的和我的是一样的。
void
在C语言中比
char
来得晚,所以有一段时间它被用作我们现在使用的
void*
来指代“指向任意数据的指针”。试着想象一下,就像是“void*”他们分配一块内存,把它放在一个指针中,然后用它来实现一个基本的列表。同样,正如@ Msalter所说的,这是C不是C++,在C++中这将是非常不合理的。@明丽在第一个玻璃看来,谁写的这个代码是一个非常低的合格程序员。
#include <stdio.h>
#include <stdlib.h>

int main() {

    void **vpa = malloc(4096);    // arr. of ptrs (to void) 
    void **currp = vpa;

    int skip_elem = 5;            //  5 * sizeof *vpa -> 5*8 bytes entry size


    for (int i = 0; i < 7; i++) {
        *currp = currp + skip_elem;
        currp += skip_elem;
    }

    for (int i = 0; i < 50; i++)
      printf("%p %p\n", vpa+i, vpa[i]);

    free(vpa);
}
0x55f9dc7922a0 0x55f9dc7922c8
0x55f9dc7922a8 (nil)
0x55f9dc7922b0 (nil)
0x55f9dc7922b8 (nil)
0x55f9dc7922c0 (nil)
0x55f9dc7922c8 0x55f9dc7922f0
0x55f9dc7922d0 (nil)
0x55f9dc7922d8 (nil)
0x55f9dc7922e0 (nil)
0x55f9dc7922e8 (nil)
0x55f9dc7922f0 0x55f9dc792318
0x55f9dc7922f8 (nil)
0x55f9dc792300 (nil)
0x55f9dc792308 (nil)
0x55f9dc792310 (nil)
0x55f9dc792318 0x55f9dc792340
...