为什么这个指针声明可以与 malloc() 一起使用?

pro*_*873 1 c malloc struct pointers

我是 C 新手,对特定指针声明有疑问:

这是我写的一个程序:

#include <stdlib.h>

struct n {

       int x;
       int y;
};


int main()
{
    struct n **p = malloc(sizeof(struct n));

    return 0;
}

Run Code Online (Sandbox Code Playgroud)

这里的声明不正确,但为什么不正确呢?

这是我的思考过程:

  • 的手册页malloc指定它返回一个指针:
The malloc() and calloc() functions return a pointer to the
allocated memory, which is suitably aligned for any built-in
type.
Run Code Online (Sandbox Code Playgroud)
  • 的类型pstruct n**称为指向另一个指针的指针。

  • 但这个声明在理论上不应该起作用,因为:

  1. malloc返回类型struct n*(指针)
  2. 并指向返回p的指针malloc
  3. 所以它本质上是一个指向另一个指针的指针
  4. 所以 的类型p已满足

抱歉,如果这是一个愚蠢的问题,但我真的很困惑为什么这不起作用。感谢您提前提供的任何帮助。

Eri*_*hil 6

无论如何调用,的返回类型malloc都不是。struct n *的返回类型mallocvoid *.

\n

struct n **使用类型值初始化对象void *会将其隐式转换为struct n **. 这种隐式转换是允许的,因为初始化规则遵循 C 2018 6.5.16.1 1 中的赋值规则,其中规定允许的赋值之一是:

\n
\n

\xe2\x80\xa6 左操作数具有原子、限定或非限定指针类型,并且(考虑左值转换后左操作数将具有的类型)一个操作数是指向对象类型的指针,另一个操作数是指向对象类型的指针的限定或非限定版本void,并且左侧指向的类型具有右侧指向的类型的所有限定符;\xe2\x80\xa6

\n
\n
\n
    \n
  1. 并指向返回p的指针malloc
  2. \n
\n
\n

否,该值p被初始化为返回的值malloc。然后p指向malloc分配的内存。

\n

struct n这段代码为 a (using )分配了足够的空间malloc(sizeof(struct n)),但却将该空间的地址分配给了 that struct n **is ,这是一个错误p。要指向 a struct n,最好使用struct n *p = malloc(sizeof (struct n));struct n *p = malloc(sizeof *p);

\n

要指向 a 的指针struct n,首先创建一些指向 a 的指针struct n,如上所示struct n *p = malloc(sizeof *p);。那么指向该指针的指针将是struct n **pp = &p;

\n

如果你想为那些指向指针的指针分配空间,你可以用 来完成struct n **pp = malloc(sizeof *pp);,然后你可以用 填充指向 的struct n指针*pp = malloc(sizeof **pp);。但是,如果没有充分的理由,您不应添加此额外的分配层。

\n

请注意,形式MyPointer = malloc(sizeof *MyPointer);通常是首选,因为前者自动使用指向的MyPointer = malloc(sizeof (SomeType));类型。MyPointer后者很容易出现错误,例如有人误解了 的类型MyPointer并且没有正确设置SomeType,或者有人后来更改了 的声明但省略了在调用中MyPointer进行相应的更改。SomeTypemalloc

\n