5

我在 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 ?谢谢!

4

2 回答 2

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];

理想情况下,重新考虑是否需要像这样动态创建对象 - 你可以使用 astd::vector或类似的代替吗?

于 2013-08-04T19:41:01.053 回答
3

在 C 中,您可以强制转换由malloc. C 为您执行此操作,但您也可以是明确的。

malloc返回一个void *或 void 指针,然后程序员可以将此返回值转换为其他指针类型。或者程序员可以依靠 C 来进行类型转换。C 使用强制类型转换的类型转换预计不会改变。

但是,依赖于 C 编译器的 C 代码可能晦涩难懂且难以阅读。开发程序员可以帮助最终必须阅读代码的维护程序员。

为返回的值添加显式转换malloc有助于必须阅读代码并确定作者意图的人。这是显式转换返回的 void 指针的真正好处malloc。这种编程实践不会误导编译器或使用一些可能会改变的神秘编译器功能。

以下三个示例突出了这种编程实践。在第一个示例中, 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 编译器。

于 2013-08-04T20:33:26.100 回答