在这个问题上,有人在评论中建议我不要使用malloc的结果。即,我应该这样做:
int *sieve = malloc(sizeof(*sieve) * length);
而不是:
int *sieve = (int *) malloc(sizeof(*sieve) * length);
为什么会这样?
在这个问题上,有人在评论中建议我不要使用malloc的结果。即,我应该这样做:
int *sieve = malloc(sizeof(*sieve) * length);
而不是:
int *sieve = (int *) malloc(sizeof(*sieve) * length);
为什么会这样?
当前回答
习惯于GCC和Clang的人被宠坏了。外面不是很好。
这些年来,我被要求使用的过时的编译器吓坏了。公司和管理者通常采用极端保守的方法来更改编译器,甚至不会测试新的编译器(具有更好的标准遵从性和代码优化)是否能在他们的系统中工作。对于正在工作的开发人员来说,实际情况是,当你在编写代码时,你需要覆盖你的基础,不幸的是,如果你不能控制什么编译器可以应用于你的代码,那么使用mallocs是一个好习惯。
我还建议许多组织应用自己的编码标准,如果定义了编码标准,那么这应该是人们遵循的方法。在缺乏明确指导的情况下,我倾向于选择最有可能在任何地方编译,而不是盲目地遵守某个标准。
根据现行标准,这是不必要的,这一论点是非常有效的。但这一论点忽略了现实世界的现实性。在一个完全由当今标准统治的世界里,我们并没有编码,而是由我喜欢称之为“地方管理的现实领域”的实用性来控制。这比太空时代更加弯曲和扭曲
YMMV。
我倾向于将使用malloc作为防御操作。不漂亮,不完美,但总体安全。(老实说,如果你没有包含stdlib.h,那么你会遇到比强制执行malloc更多的问题!)。
其他回答
不强制强制强制强制转换malloc的结果,因为它返回void*,并且void*可以指向任何数据类型。
在C语言中,您得到了从void*到任何其他(数据)指针的隐式转换。
这就是GNU C库参考手册所说的:
您可以将malloc的结果存储到任何指针变量中强制转换,因为ISO C会自动将类型void*转换为另一个必要时的指针类型。但演员阵容在上下文中是必要的而不是赋值运算符,或者如果您可能希望代码运行在传统C。
事实上,ISO C11标准(第47页)是这么说的:
如果分配成功,则返回的指针将适当对齐它可以分配给指向任何类型对象的指针基本对齐要求,然后用于访问这样的对象或此类对象的数组(直到空间被显式释放)
现在不需要强制转换malloc()返回的值,但我想补充一点,似乎没有人指出:
在古代,也就是说,在ANSI C提供void*作为指针的通用类型之前,char*是这种用法的类型。在这种情况下,强制转换可以关闭编译器警告。
参考:C常见问题解答
malloc的主要问题是获得正确的大小。
malloc()返回的内存是非类型的,由于简单的强制转换,它不会神奇地获得有效的类型。
我想这两种方法都很好,选择应该取决于程序员的意图。
如果为类型分配内存,则使用强制转换。
ptr=(T*)malloc(sizeof(T));
如果为给定指针分配内存,则不要使用强制转换。
ptr=malloc(sizeof*ptr);
Ad 1
第一种方法通过为给定类型分配内存,然后将其强制转换以确保分配给正确的指针,从而确保正确的大小。如果使用了不正确的ptr类型,则编译器将发出警告/错误。如果ptr的类型被更改,那么编译器将指出代码需要重构的地方。
此外,第一种方法可以组合成类似于C++中新运算符的宏。
#define NEW(T) ((T*)malloc(sizeof(T)))
...
ptr = NEW(T);
此外,如果ptr为void*,则此方法有效。
Ad 2
第二个方法不关心类型,它通过从指针的类型中获取数据来确保正确的大小。这种方法的主要优点是,每当ptr的类型发生变化时,都可以自动调整存储大小。它可以在重构时节省一些时间(或错误)。
缺点是,如果ptr为空,则该方法不起作用,但它可能被认为是一件好事。而且它不适用于C++,因此不应在C++程序将要使用的头中的内联函数中使用。
就我个人而言,我更喜欢第二种选择。