在这个问题上,有人在评论中建议我不要使用malloc的结果。即,我应该这样做:

int *sieve = malloc(sizeof(*sieve) * length);

而不是:

int *sieve = (int *) malloc(sizeof(*sieve) * length);

为什么会这样?


当前回答

不强制强制强制强制转换malloc的结果,因为它返回void*,并且void*可以指向任何数据类型。

其他回答

void指针是一个通用对象指针,C支持从void指针类型到其他类型的隐式转换,因此不需要显式类型转换。

然而,如果您希望相同的代码在不支持隐式转换的C++平台上完美兼容,则需要进行类型转换,因此这一切都取决于可用性。

在C语言中,您得到了从void*到任何其他(数据)指针的隐式转换。

正如其他人所说的,它不是C所需要的,而是C++所需要的。包括强制转换可以允许C程序或函数编译为C++。在C中,这是不必要的,因为void*会自动安全地升级为任何其他指针类型。但如果你当时就投了,如果你忘了包括,它会隐藏一个错误stdlib.h。这可能会导致崩溃(更糟的是,不会导致崩溃直到稍后在代码的某个完全不同的部分)。因为stdlib.h包含找到malloc的原型。在由于没有malloc的原型,标准要求C编译器假设malloc返回int。如果没有强制转换当该整数被分配给指针时发出警告;然而,在演员阵容中,这个警告并没有产生,隐藏了一个bug。

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++程序将要使用的头中的内联函数中使用。

就我个人而言,我更喜欢第二种选择。

malloc的转换在C中是不必要的,但在C++中是必需的。

C中不需要铸造,因为:

在C的情况下,void*会自动安全地升级为任何其他指针类型。如果您忘记包含<stdlib.h>,它可能会隐藏错误。这可能会导致崩溃。如果指针和整数的大小不同,则通过强制转换隐藏警告,可能会丢失返回地址的位。如果指针的类型在声明时发生了更改,那么可能还需要更改调用和强制转换malloc的所有行。

另一方面,强制转换可能会增加程序的可移植性。即它允许C程序或函数编译为C++。