假设“structName”是一个已定义的结构:
structName ** sarray = (structName **) malloc(0 * sizeof(structName *));
我知道它创建了一个指向sarray结构指针的指针,但为什么(structName **)放在表达式的开头呢?另外,为什么在malloc调用中结构大小乘以0?
代码的来源是here
答案 0 :(得分:2)
malloc
返回void *
。指针sarray
的类型为structName **
。 (structName **)
是一种类型广告,将void *
转换为structName **
。指针在C中非常具有延展性; malloc
将始终返回可以安全地转换为任何类型指针的内容。在这种情况下,您有一个指向structName *
。
sizeof(structName *)
乘以0
符合您的想法,向malloc
询问零长度的内存块。我怀疑sizeof
在那里,因为作者认为它是标准模式。你可以删除它而没有后果,只提供0.鉴于realloc
适用于NULL
参数,你也可以将sarray
初始化为NULL
。
对于记录,malloc
:
如果请求的空间大小为零,则行为为 implementation- defined:返回空指针,或者 行为就像大小是一些非零值,除了 返回的指针不得用于访问对象。
因此初始调用可能会或可能不会返回NULL
,结果基本相同:通过指针访问任何内容都会产生不确定的结果。
答案 1 :(得分:1)
(structName **)
的原因是将malloc()
的返回值从void *
转换为(structName **)
,因此sarray
的分配不会产生不兼容的类型错误。
乘以零的原因是与以下语句的兼容性:
long sarray_len = 0;
如果示例选择以
开头long sarray_len = initialCount;
相反,malloc
必须是
structName ** sarray = (structName **) malloc(initialCount * sizeof(structName *));
答案 2 :(得分:0)
malloc函数返回一个类型为(void *)的指针。 (structName **)将该指针强制转换为类型(structName **)。 C中不需要此演员表。 他乘以0是因为他不想分配任何结构,并等待稍后重新分配。
答案 3 :(得分:0)
为什么
(structName **)
位于表达式的开头?
它被称为type casting。 malloc
returns a void *
投放到structName **
,以便将其分配到sarray
。
另外,为什么在malloc调用中结构大小乘以0?
代码模式malloc(size * sizeof(datatype))
通常随处可见,因此在那里使用了乘法,IMO。
答案 4 :(得分:0)
structName ** sarray = (structName **) malloc(0 * sizeof(structName *));
相当于:
structName ** sarray = NULL;
答案 5 :(得分:0)
(structName **)
之前的malloc
是错误的。它在20世纪70年代被要求,但自1989年以来一直是个错误。自1989年以来,许多人都没有更新他们的学习材料; - )
充其量是冗余文本(通常应避免使用冗余文本,因为它会使重要文本更难阅读),最糟糕的是它可以隐藏错误。有关该主题的进一步阅读see this thread。
关于第二部分,0 * sizeof(structName *)
。这当然是0
,你可能会问这个人为什么不写0
。
原因是该人符合使用malloc的特定风格。符合模式是一种最小化错误的方法。如果您经常阅读本网站,您会发现错误使用malloc是人们无法追踪的最常见错误来源之一。使用的模式是:
T *ptr = (T *) malloc( number_of_elements * sizeof(T) );
分配一定数量的T
类型元素的数组。即使数字为0
(但负数不合法),这也是合法的;在这种情况下,它可以返回空指针,也可以返回非空指针。无论哪种情况,当然,您无法尝试访问任何数组元素。
这种模式很常见,但正如链接线程中所提到的,存在问题,自1989年以来有了更好的选择。
NB。考虑使用calloc
来分配内存。它稍微清楚一点,两个数字用逗号而不是乘法运算符分隔,并且在某些操作系统(例如Linux)上它的执行速度比malloc
快。