C语言 这行代码到底在做什么



假设"structName"是一个定义的结构:

structName ** sarray = (structName **) malloc(0 * sizeof(structName *));

我知道它创建了一个指向名为 sarray 的结构指针的指针,但为什么在表达式的开头放置了 (structName **(?另外,为什么在 malloc 调用中结构大小乘以 0?

代码的源代码在这里

malloc 返回void * 。指针sarray的类型为 structName **(structName **)是类型转换,将void *转换为structName **。指针在 C 语言中具有很强的延展性; malloc将始终返回可以安全地投射到任何类型的指针的内容。在这种情况下,您有一个指向 structName * 的指针。

sizeof(structName *)乘以0会按照您的想法进行操作,要求malloc提供零长度的内存块。我怀疑sizeof在那里,因为作者认为这是标准模式。您可以删除它而不会产生任何后果,只需提供 0。鉴于realloc适用于NULL参数,您也可以将sarray初始化为NULL

为了记录,为了malloc

如果请求的空间大小为零,则行为为 实现定义:返回空指针,或 行为就像大小是某个非零值,除了 返回的指针不得用于访问对象。

因此,初始调用可能会也可能不会返回NULL,结果基本相同:通过指针访问任何内容都应具有未定义的结果。

(structName **)

原因是将malloc()的返回值从 void * 转换为 (structName **) ,因此对 sarray 的赋值不会产生不兼容的类型错误。

以零的原因是与以下语句的兼容性:

long sarray_len = 0;

如果示例选择以

long sarray_len = initialCount;

相反,malloc必须是

structName ** sarray = (structName **) malloc(initialCount * sizeof(structName *));

.

malloc 函数返回一个类型的指针 (void *(。(structName **( 将该指针强制转换为类型 (structName **(。在 C 语言中不需要此强制转换。他乘以 0,因为他还不想分配任何结构,并等待稍后重新分配。

为什么在表达式的开头放置(structName **)

它称为类型转换。 malloc 返回一个 void *,该被强制转换为 structName **以便可以将其分配给sarray

另外,为什么在 malloc 调用中结构大小乘以 0?

代码模式malloc(size * sizeof(datatype))通常在任何地方都遵循,因此在那里使用了乘法,IMO。

structName ** sarray = (structName **) malloc(0 * sizeof(structName *));

等效于 :

structName ** sarray = NULL;

malloc前面的(structName **)是一个错误。 它在 1970 年代是必需的,但自 1989 年以来一直是一个错误。自1989年以来,许多人没有更新他们的学习材料;-(

充其量它是冗余文本(通常应避免冗余文本,因为它会使重要文本更难阅读(,最坏的情况是它可以隐藏错误。有关该主题的进一步阅读,请参阅此线程。


关于第二部分,0 * sizeof(structName *).这当然是0,你可能会问为什么这个人不只是写0.

原因是该人符合使用malloc的特定风格。符合模式是最小化错误的一种方法。如果您经常阅读此站点,您就会知道不正确使用 malloc 是人们难以追踪的最常见的错误来源之一。 使用的模式是:

T *ptr = (T *) malloc( number_of_elements * sizeof(T) );

它分配一定数量的 T 类型元素的数组。即使数字0,这也是合法的(但对于负数则不合法(;在这种情况下,它可能返回空指针或非空指针。在任何一种情况下,您都不能尝试访问任何数组元素,当然。

这种模式很常见,但如链接线程中所述,存在问题,自 1989 年以来一直有更好的选择。

铌。请考虑使用 calloc 来分配内存。稍微清楚一点的是,这两个数字用逗号而不是乘法运算符分隔,在某些操作系统(例如Linux(上,它的执行速度可以比malloc快。

相关内容

  • 没有找到相关文章

最新更新