Interfacing C++11 code to some C callbacks, and I have to pass const char * const *
, i.e. an array of strings. Here is a cut-down version of my code:
int main(int,char**){
const int cnt = 10;
const char * const * names =
static_cast<const char * const *>(malloc( sizeof(char*) * cnt));
//... allocating names[0], etc. coming soon ...
the_c_function(names);
free(names);
return 0;
}
So I worked out how to use malloc
in C++, but I'm stuck on free
, as it tells me: "invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]"
My first reaction was "Eh? Why do you care, all you have to do is free the pointer." Second reaction was to just cast it away. But this gets rejected by the compiler:
free( const_cast<void*>(names) );
And this does too:
free( static_cast<void*>(acctnames) );
E.g. "invalid static_cast from type ‘const char* const*’ to type ‘void*’".
What does work is a good 'ole C cast:
free( (void*)(acctnames) );
Is that safe, or am I missing something here? (valgrind
tells me "All heap blocks were freed -- no leaks are possible", which is some comfort!)
P.S. Using g++ 4.8.1, on Linux.
UPDATE: explanation of why free()
wants a non-const pointer is here: Unable to free const pointers in C
(though I found barak manos's answer below clearer on that).
const void is a type which you can form a pointer to. It's similar to a normal void pointer, but conversions work differently. For example, a const int* cannot be implicitly converted to a void* , but it can be implicitly converted to a const void* .
E2158 Operand of 'delete' must be non-const pointer (C++) It is illegal to delete a variable that is not a pointer. It is also illegal to delete a pointer to a constant.
const_cast
can only remove const
and volatile
qualifiers; it can't change the pointer type. Conversely, static_cast
can change the type, but can't remove top-level qualifiers. However, conversion to void*
from a non-const object pointer type is implicit, so this should work:
free( const_cast<const char**>(names) );
More tricky conversions, would require both a const_cast
and a static_cast
(or even reinterpret_cast
in weird cases).
The evil C cast can combine both const_cast
and static_cast
, so could be used as a shortcut for both. However, that's a bad idea since it's more dangerous: if you specify the wrong type, then it will force the conversion via reinterpret_cast
, potentially causing weird runtime behaviour where safer casts would fail at compile time.
However, there's no need for any cast here: the conversion from X*
to X const*
can be done implicitly, so just change the type of the local pointer:
const char ** names = static_cast<const char **>(malloc( sizeof(char*) * cnt));
the_c_function(names); // OK - adds const
free(names); // OK - no const to remove
Finally, since this is C++, there's no need to muck around with malloc
and pointers at all (unless the C API is evil enough to require that it be given memory from malloc
):
std::vector<const char*> names(cnt);
the_c_function(names.data());
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