我在C标题中有以下代码
typedef struct {
kiss_fft_scalar r;
kiss_fft_scalar i;
} kiss_fft_cpx;
我在测试程序中实现了以下代码
kiss_fft_cpx *fin = malloc(4*sizeof(kiss_fft_cpx));
它给了我错误消息:“void类型的值不能用于初始化'kiss_fft_ctx'类型的实体。”
我正在使用Visual Studio C / C ++ win32控制台项目。
谁能告诉我如何在这里正确使用malloc?谢谢!
答案 0 :(得分:13)
您需要像这样强制转换返回类型:
kiss_fft_cpx *fin = (kiss_fft_cpx*) malloc(4*sizeof(kiss_fft_cpx));
但其含义是您将代码编译为C ++而不是C,因为这是C ++错误而不是C错误。您可能想检查文件扩展名和/或编译器设置。
如果您真的 使用C ++,则至少应使用new
而不是malloc
:
kiss_fft_cpx *fin = new kiss_fft_cpx[4];
并且理想情况下需要重新考虑是否需要像这样动态创建对象 - 您可以使用std::vector
或类似的吗?
答案 1 :(得分:3)
在C中,您可以转换malloc
返回的void指针。 C为你做这件事,但你也可以是明确的。
malloc
返回void *
或void指针,然后程序员可以将此返回值转换为其他指针类型。或者程序员可以依靠C来进行类型转换。使用演员表的C类型转换预计不会改变。
但是,依赖于C编译器的C代码可能会很难以阅读。 开发程序员可以帮助最终必须阅读代码的维护程序员。
为malloc
的返回值添加显式强制转换可以帮助那些拥有的人
阅读代码并确定作者的意图。这是明确地转换malloc
返回的void指针的真正好处。这种编程实践
不要误导编译器或使用可能会改变的某些神秘的编译器功能。
以下三个例子突出了这种编程实践。在第一个例子中,
malloc
(在<stdlib.h>
中定义)是明确的,并且有些琐碎的工作
进行。
#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = (char *) malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// prints abc at the console
}
在第二个示例中,唯一的区别是<stdlib.h>
被注释掉了。该
代码仍然运行并产生相同的结果。现在,为什么这个有效的“原因”是相当直接的。当C没有找到函数的原型时,它假定函数返回int
,但malloc
返回一个void指针。在这种情况下,显式转换已经告诉C编译器以及源的碳单元,malloc
返回的值应该转换为字符指针。
//#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = (char *) malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// prints abc at the console
}
最终(是的)示例不发布演员而不包括<stdlib.h>
。 Eclipse编辑器和编译器都抱怨这个代码(正如他们应该的那样)。编译器消息是
..\main.c(18) : warning C4047: '=' : 'char *' differs in levels of indirection from 'int'
源代码是:
//#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// compiler displays a "warning" and prints abc at the console
}
更改示例3以包含没有警告的结果,程序按预期运行。但是,示例2和3都缺少显式强制转换,并且在使用此样式编写的代码的生命周期内,此类代码将更加昂贵,并且更可能被人类错误地更改(因此额外费用),而不是显式使用由C编译器。