“是什么意思?”*((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
指向一些被组织成若干“条目”的内存。该代码通过在指向下一个条目的每个条目的开头放置一个指针(achar*
)将其放入一个链表中
给定指向当前条目的指针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 ** /代码>我得到关于
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
...