2014-10-06 108 views
0

假设“structName”是定义的结构:这段代码真的在做什么?

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

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

代码的源是here

+0

我的猜测是'0'是一个硬编码的幻数,而你的前任曾经把它作为一个非零值。 '(structName **)'是一个类型转换。编辑:它看起来像数组应该增长使用'realloc',但开始为'0'大小。 'sizeof(structName *)'可能只是包含在内,因为它的良好实践。 – acbabis 2014-10-06 23:32:07

+0

代码开始为将根据需要展开的数组分配一个零大小的块(或试图分配一个块)。这是有效的,但是任何做这种事情的人都需要小心 - malloc()被指定为可以将NULL或地址返回到零大小的内存块。在示例代码的情况下,这是可以的,因为在扩展零大小的块或NULL指针时,realloc()将表现良好。 – 2014-10-06 23:34:50

+0

问:这行代码真的在做什么?简答:没有用。较长的回答:1)我推迟'malloc()',直到我有一个非零值分配,2)我一般喜欢形式'malloc(sizeof结构名);',而不是指针指针**)。 – FoggyDay 2014-10-06 23:42:15

回答

2

malloc返回void *。指针sarray的类型为structName **(structName **)是一种类型转换,将void *转换为structName **。指针在C中非常可塑; malloc将始终返回可以安全地投射到任何种类的指针的东西。在这种情况下,您有一个指向structName *的指针。

乘以sizeof(structName *)0做你的想法,要求malloc一个零长度的内存块。我怀疑sizeof在那里,因为作者认为它是标准模式。你可以删除它,没有任何后果,只是提供0.鉴于reallocNULL参数一起使用,你也可以只是初始化sarrayNULL

对于记录,为malloc

如果所请求的空间的大小是零,则该行为定义 implementation-:返回任一个空指针,或 行为是因为如果大小是非零值,但不应使用返回的指针访问对象。

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

+0

谢谢。我现在明白了。 – AJPennster 2014-10-07 00:29:27

0

malloc函数返回类型为(void *)的指针。 (structName **)将该指针转换为类型(structName **)。这种转换在C. 中不是必需的,他乘以0,因为他不想分配任何结构,并且稍后等待重新分配。

0

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

它被称为type castingmallocreturns a void *这是铸造到structName **,以便它可以被分配到sarray

此外,malloc调用中为什么struct size乘以0?

编码模式malloc(size * sizeof(datatype))通常随处可见,因此在那里使用乘法IMO。

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

等同于:

structName ** sarray = NULL; 
1

的原因(structName **)是的malloc()返回值从void *转换为(structName **),所以分配给sarray不会产生不兼容的类型错误。

原因被零乘法与下面的语句兼容性:

long sarray_len = 0; 

如果例如选择了先从

long sarray_len = initialCount; 

代替,那么malloc必须是

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

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年以来存在更好的选择。

注意:考虑使用calloc分配内存。由于两个数字之间用逗号分隔,而不是乘法运算符,所以稍微清晰一些,在某些操作系统(例如Linux)上,它的执行速度可能快于malloc