I have the following code in the C header
typedef struct {
kiss_fft_scalar r;
kiss_fft_scalar i;
} kiss_fft_cpx;
And I implemented the following code in the test program
kiss_fft_cpx *fin = malloc(4*sizeof(kiss_fft_cpx));
And it gave me the error message: "A value of type void cannot be used to initialize an entity of type 'kiss_fft_ctx' ".
I am using Visual Studio C/C++ win32 console project.
Can anyone tell me how to correctly use the malloc here? Thanks!
You need to cast the return type like this:
kiss_fft_cpx *fin = (kiss_fft_cpx*) malloc(4*sizeof(kiss_fft_cpx));
but the implication is that you're compiling your code as C++ rather than C, because that's a C++ error rather than a C error. You might want to check your file extension and/or your compiler settings.
If you really are using C++, you should at a minimum use new
rather than malloc
:
kiss_fft_cpx *fin = new kiss_fft_cpx[4];
and ideally rethink whether you need to be creating objects dynamically like this - could you be using a std::vector
or similar instead?
In C you can cast the void pointer returned by malloc
. C does this for you but you can also be explicit.
malloc
returns a void *
or void pointer, this returned value can then be cast by a programmer into other pointer types. Or the programmer can rely on C to do the type conversion. C's type conversion using casts is not expected to change.
However, C code that relies on the C-compiler can be obstuse and difficult to read. A development programmer can help maintenance programmers who will eventually have to read the code.
Adding an explicit cast to the returned value of malloc
helps humans who will have
to read the code and determine the author's intent. This is the real benefit of explicitely casting the void pointer returned by malloc
. This programming practice does
NOT mis-direct the compiler or make use of some arcane compiler feature that might change.
The following three examples highlight this programming practice. In the first example,
malloc
(which is defined in <stdlib.h>
) is explicitely cast and some trivial work is
performed.
#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
}
In this second example, the only difference is that <stdlib.h>
is commented out. The
code still runs and produces the same result. Now, the "why" of why this works is fairly direct. When C does NOT find the prototype for a function it assumes that the function returns an int
, but malloc
returns a void pointer. In this case the explicit cast has told the C compiler, as well as the source's carbon unit, that the value returned by malloc
should be converted into a character pointer.
//#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
}
The final (yeah) example does NOT issue the cast and does not include <stdlib.h>
. Both the Eclipse editor and the compiler complain about this code (as they should). The compiler message is
..\main.c(18) : warning C4047: '=' : 'char *' differs in levels of indirection from 'int'
And the source code is:
//#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
}
Changing example 3 to include results in no warnings and the program runs as intended. However, both examples 2 and 3 lack the explicit cast and over the lifetime of code written in this style such code will be more expensive and more likely to be changed incorrectly by humans (thus the additional expense) than explicit using casts which are supported by C-compilers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With