*( char** ) 实现什么类型的转换?

What type of cast does *( char** ) achieve?

*( char** )完成什么类型​​的转换?
它似乎用 ** 创建了一个指向指针 ("double pointer") 的指针。但是括号外的*让我很困惑......下面是上下文中的演员表:

void mem_test ( void )
{
    void* m1;
    void* m2;

    ...

    m1 = 0;

    while ( ( m2 = malloc( 10001 ) ) != 0 )
    {
        *( char** ) m2 = m1;  // what does this cast mean?

        m1 = m2;
    }

    ...
}

它的另一个令人困惑的变体出现在以下代码段中。演员在这个场景中完成了什么,它与上面的不同吗?

void mpenter ( void );  // a function with no parameters and no return value

...

uchar* code;

...

*( void ( ** ) ( void ) ) ( code - 8 ) = mpenter;  // what does this cast mean?

这种演员表的正确名称是什么? IE。我应该搜索什么以了解更多信息?

mem_test

我们来剖析这个step-by-step。为简单起见,假设我们使用的是 64 位架构,其中指针的大小为 8 个字节。

  • m2 = malloc( 10001 )m2 分配给新分配的内存块。
  • (char **) m2 说 "let's pretend the first 8 bytes of memory at address m2 is a char*, and point at that -- resulting in a char**"
  • *(char **) m2 取消引用上面的内容,导致 l-value 到 char* (在 C 语言中)。记住 l-values 是可写的。
    • 在 C++ 中,它会导致对 char* 的引用,即 char*&
  • *(char **) m2 = m1;m1的值写入上面创建的l-value。

编写该代码的另一种方法是:

char* pCurrentBuffer;
char* pPreviousBuffer;

pPreviousBuffer = NULL;
while ( ( pCurrentBuffer = malloc( 10001 ) ) != NULL )
{
    char** ppPreviousBuffer = (char**)pCurrentBuffer;
    *ppPreviousBuffer = pPreviousBuffer;

    pPreviousBuffer = pCurrentBuffer;
}

惊喜(!),最后,它创建了一个链表。 (从技术上讲,它是一个颠倒的 linked-list 因为它们都是前一个指针而不是后一个指针,但我在开玩笑)

mpenter

这是将地址 code - 8 处的 8 个字节转换为 pointer-to-function-pointer,以便它可以将函数 mpenter 的地址分配到该位置。

  • void (*)(void) 是指向不带参数的函数的指针,returns void.
  • 通过扩展,void (**)(void) 是指向上述类型的 function-pointer 的指针。
  • 取消引用,生成 l-value 到 function-pointer。
    • 在 C++ 中,它会创建对 function-pointer 的引用,如果这更容易推理的话。
  • 分配它会将 mpenter 的地址写入 l-value(即地址 code - 8 处的 8 字节内存)

从指针获取负偏移量是不常见的,但如果 code 指向某种结构的中间,它可能是合法的(在这个词的某种宽泛意义上)。