【问题标题】:pointer to malloc?指向malloc的指针?
【发布时间】:2012-08-17 14:38:39
【问题描述】:
struct node* new_node =
            (struct node*) malloc(sizeof(struct node));

我不明白这里的 * :...(struct node*) malloc(siz... 一、*属于node还是malloc?这是什么意思?指针与内存函数 malloc 有什么关系? 我真的对 * 位置感到困惑

谢谢

【问题讨论】:

标签: c pointers struct


【解决方案1】:

C 中括号中的类型名称(例如(struct node *))称为“强制转换”。这是一种将表达式类型更改为命名类型的方法,通常与指针一起使用。

但是,此代码忽略了Do I cast the result of malloc 中的建议。 不需要这里需要演员表,这使得(在我看来,如果您遵循该链接,也许并不奇怪)相当糟糕的代码。

编写此分配的最佳方式是:

struct node * new_node = malloc(sizeof *new_node);

这仅提到了一次类型,删除了可能引入错误且阅读起来既无意义又麻烦的强制转换,并避免在指定要分配多少内存时引入脆弱性。赢了,赢了。

【讨论】:

  • 在我看来,node_t* new_node = malloc (sizeof (node_t)); 远没有眼痛。
【解决方案2】:
struct node     <= type
*new_node       <= pointer named new_node (of type struct node)
=               <= assignment
(struct node *) <= cast to pointer of type struct node
malloc(SIZE)    <= returns pointer of type void, thus needs cast

【讨论】:

  • = 在这个例子中不是赋值,它是初始化语法的一部分。并不是说它在 C 中产生了很大的实际差异,但这就是 C 语法所说的。
  • 我宁愿说类型是struct node*(指向节点的指针)。此外,您对需要强制转换的 void 指针是不正确的。
  • @Lundin:语法上,struct node类型说明符*new_node声明符。当然,new_node 的类型确实是struct node*,但在声明中* 不是类型说明符的一部分。例如struct node *ptr, instance;.
  • @SteveJessop 这就是为什么在一行上声明多个变量是个坏主意。如果你在自己的一行上声明每个变量,那么我的说法成立,那么你就不需要知道或担心 C 标准的形式乱码。
  • @Lundin:当然,或者您可以阅读和理解标准;-p 还有其他复杂的声明,其中“类型后跟对象名称”的简化概念被打破,例如指针指向-大批。因此,IMO 值得了解实际的语法(我的意思是,主要了解它并能够查找尴尬的细节),而不是希望摆脱简化的语法并总是要求其他人使用足够的 typedefs 来简化版本保持正确。
【解决方案3】:

(struct node*)cast,这是一种显式类型转换。 * 属于struct node,表明请求的类型是指向struct node 变量的指针。 malloc() 总是返回一个void*,一个空指针。

malloc 的函数定义是void* malloc (size_t size);(在这种情况下* 也属于void)。

编写您问题中发布的代码的人将此 void 指针转换为 struct node*。他们为什么这样做并不清楚,他们要么对 C 中的指针转换如何工作感到困惑,而且也不知道这种转换的危险,要么代码是为 C++ 编写的。

C 语言中的 void 指针是一种通用指针类型,可以转换为任何其他指针类型,无需强制转换 (1)。

但是,在 C++ 中,转换 void 指针时必须始终进行强制转换,因为 C++ 的类型转换规则比 C 更严格,并且强制执行显式转换。

在 C 中转换 malloc() 的结果是危险的,并且被认为是一个错误 (2),因为除非通过 #include 提供正确的函数原型,否则编译器默认行为会启动,它会错误地认为 malloc 返回 int .根据特定系统的指针和整数宽度,它可能工作得很好,或者可能导致程序崩溃和/或内存泄漏。

然而,在 C++ 中强制转换 malloc() 的结果是必要的。


参考资料:

  1. ISO 9899:2011 6.3.2.3/1。
  2. Specifically, what's dangerous about casting the result of malloc?

【讨论】:

  • “Typecasting”更准确地称为“casting”。并且“显式 [type]cast” 是多余的;所有强制转换都是显式的,隐式转换不是强制转换。
  • @KeithThompson 好吧,这有点挑剔,但我更新了帖子,所以它现在使用 C 标准中使用的正式术语:castimplicit conversion显式转换。但是,我不太确定这对初学者程序员有什么不同。
  • 我从这里拿的:geeksforgeeks.org/archives/860 那是 C++ 还是只是一个糟糕的编写代码?
  • @MikaStern 这绝对是 C。除了 malloc 转换之外,代码实际上看起来写得很好。
【解决方案4】:

* 用于类型。这里的类型是struct node*(指向struct node的指针)。

它不是“连接”到malloc 函数,而是“连接”到类型。 malloc() 返回一个指针,因此您也将返回值分配为一个指针。

【讨论】:

    【解决方案5】:

    只是type casting

    malloc 返回一个void 指针(没有任何类型的指针)。 (struct node *) 表示您将一个类型关联到malloc 返回的 void 指针。 另见this

    【讨论】:

      【解决方案6】:

      这只是一个类型转换。实际上 malloc 函数返回 void pointer (void *) ,这意味着它不特定于任何数据结构或数据类型。它返回一个通用指针。 通过类型转换,我们使返回值具体化,在这种情况下 (struct node *) 是指向结构节点类型的指针。

      简单来说,我们可以说我们正在将 void 指针 (void *) 转换为 struct 指针 (struct node *)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-03
        • 1970-01-01
        • 2012-04-18
        相关资源
        最近更新 更多