我正在尝试阅读一些 CPython 源代码,特别是 obmalloc.c
( https://github.com/python/cpython/blob/master/Objects/obmalloc.c )。当我阅读 malloc 和 free work 的等价物时,我想到了这些行:
pymalloc_free(void *ctx, void *p){
...
*(block **)p = lastfree = pool->freeblock;
pool->freeblock = (block *)p;
...
}
和
pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes){
bp = pool->freeblock;
if ((pool->freeblock = *(block **)bp) != NULL) {
...
}
...
}
这里的 block 是 typedef uint8_t block ;
而 pool
结构是:
struct pool {
...
block *freeblock;
...
}
我无法理解所有使用 *(block **)p
的代码。我的问题是:
- 这些作业是如何进行的?
- 我认为如果
p
是block*
类型,那么*(block **)p
应该是幂等的,为什么不是在这种情况下。 - 这似乎是用来实现链表的,这个机制是如何工作的,它与
*(block **)p
有什么关系?
最佳答案
代码是
pymalloc_free(void *ctx, void *p){
...
*(block **)p = lastfree = pool->freeblock;
pool->freeblock = (block *)p;
...
}
首先,block
是 uint8_t
的类型定义,即一个 8 位字节。它在这里仅用作语义标记,表示指针指向要分配的内存块,而不是某处的任何随机字节或字符串。
你问:
- I thought that
*(block **)p
is supposed to be idempotent ifp
is of typeblock*
, why is not in this case.
不是,它会将 block *
转换为 block **
然后取消引用指针。请注意,在这种情况下,给定的指针是 void *
,而不是 block *
。
- How these assignments are working?
访问 p
指向的内存就像它指向 block *
一样。而不是 Actor 。如果有一个中间变量,因为它会使正在发生的事情更加明显:
block **bpp = p
*bpp = lastfree = pool->freeblock;
和
bp = pool->freeblock;
block **bpp = bp;
if ((pool->freeblock = *bpp) != NULL) {
}
- This seems to be used to implement a linked list, how that mechanism works and how it relates to *(block **)p?
空闲内存块都是特定大小的字节 block 。空闲 block 的第一个 sizeof (block *)
(即 sizeof (uint8_t *)
)字节指向下一个字节 block ,因此指向开始的指针可以是转换为指向指针的指针并取消引用以获取位于第一个字节中的this指针值。
请注意,该 block 还必须从可被 _Alignof (block *)
整除的地址开始,pymalloc
会仔细维护该地址。
关于python - 如果 `*(block **)p` 的类型为 `block`,为什么 `p` 与 `block*` 不同? [CPython 源代码],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54375661/