假设"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
快。