I got this problem:
invalid conversion from ‘void*’ to ‘uint8_t*’
When doing this:
int numBytes;
uint8_t *buffer;
buffer=malloc(numBytes); //error here, why?
or must I have to put it like this?
buffer=malloc(numBytes);
Please explain this.
You cannot implicitly cast from void * in C++ (unlike C in this respect). You could do:
buffer = static_cast<uint8_t *>(malloc(numBytes));
but really, you should just be using new/delete instead of malloc/free!
In C++ it is not allowed to simply assign a pointer of one type to a pointer of another type (as always there are exception to the rule. It is for example valid to assign a any pointer to a void pointer.)
What you should do is to cast your void pointer to a uint8_t pointer:
buffer = (uint8_t *) malloc (numBytes);
Note: This is only necessary in C++, in C it was allowed to mix and match pointers. Most C compilers give a warning, but it is valid code.
Since you're using C++ you could also use new and delete like this:
buffer = new uint8_t[numBytes];
and get rid of your buffer using:
delete[] buffer;
In general you shouldn't use malloc and free unless you have to interface with c libraries.
Malloc returns a void pointer; when you use it, you have to cast the return value to a pointer to whatever datatype you're storing in it.
buffer = (uint8_t *) malloc(numBytes);
Related
There is a C-style string and I need to free the memory of it. I saw the following code sample but got confused about why (void*) is there.
char *data = "abc";
free( (void*)data );
Just two questions:
Why not simply free(data)?
Is (void*) conversion is a must?
Many thanks.
No, it's not necessary; the free() call is wrong and you cannot do this.
The cast is a huge blinking, bouncing, and screaming warning flag that the originating programmer was confused.
It's undefined behavior to pass a pointer not returned by a previous call to malloc() or one of its friends to free(). The cast is the least of the problems here.
You can never "free" the memory used by a string literal, since that memory is never allocated in some way that the program controls. It's not on the heap, and the heap is where dynamic memory allocation/deallocation typically happens. Your intention is wrong.
All you can do is set the pointer to NULL:
data = NULL;
that will not in any way "free" the memory used behind the scenes to hold the character data "abc" though, but that's fine.
Is an error to call free() since is not allocated using (m/c/re)alloc.
As pointed out by Jens Gustedt, a cast is only needed when you pass a const pointer because free() takes a void *, not a const void *:
const int *x = malloc(sizeof(int));
free((void *)x);
Without a cast you get:
demo.c:8:5: warning: passing argument 1 of ‘free’ discards ‘const’ qualifier from pointer target type [enabled by default] In file included from demo.c:2:0: /usr/include/stdlib.h:488:13: note: expected ‘void *’ but argument is of type ‘const int *’
The cast is unnecessary. In C, a void* is implicitly convertible to and from other pointer types. free expects a void*, so no cast is required from another pointer type.
(Of course, as already pointed out, the code is obviously problematic altogether, so don't read into it too much.)
So, your premise here is incorrect, you do not need to free your "data" at all, it will most likely cause a crash if you do. You should only call free for data that has come from malloc, and "abc" is not one of those.
Second, if you are using C, then you should do:
char *data = malloc(4);
strcpy(data, "abc");
...
free(data);
In C++ we also can't convert a void * [the return value from malloc] to char *, so you would need char *data = (char *) malloc(4);, but free(data) should still work. Some compilers may issue warnings for this, and the standard MISRA, for example, does not allow ANY automatic conversions of C types, so explicit casts are REQUIRED here [not because the language says so, but because the MISRA standard does, and there are "checking software" that reads the source code to check these sort of criteria are met].
Of course, in "fresh"[1] C++, we should not use malloc or free, but new and delete:
char *data = new char[4];
strcpy(data, "abc");
....
delete [] data;
[1] As in "code written as C++ from scratch".
void* buffer = (void*)malloc(100);
By prefixing the malloc() function with (void*), what is being achieved, are we overriding the return type?
Nothing is achieved since malloc already returns a void pointer. This is equivalent to:
void* buffer = malloc(100);
The return type of the call to malloc is being explicitly cast to a void pointer. This is sort of redundant, as it already returns a void*, but is probably possibly present to clarify the developer's intention (or he just screwed up).
In this particular case, it does nothing. However, since C++ is much more strict than C regarding type safety, you generally need to cast the return of malloc:
void* x = malloc(100); //OK in C/C++
int* y = malloc(100); //OK in C, error in C++
int* z = (int*)malloc(100); //OK in C/C++, not recommended for C
However, since you use C++, I can't not tell you that you should use new instead.
Code:
void *buff;
char *r_buff = (char *)buff;
I can't understand the type casting of buff. Please help.
Thank you.
buff is a pointer to some memory, where the type of its content is unspecified (hence the void).
The second line tells that r_buff shall point to the same memory location, and the contents shall be interpreted as char(s).
buff is typed as a void pointer, which means it points to memory without declaring anything about the contents.
When you cast to char *, you declare that you're interpreting the pointer as being a char pointer.
In well written C++, you should not use C-style casts. So your cast should look like this:
void *buff;
char *r_buff = static_cast<char *>(buff);
See here for an explanation of what the C++ casting operators do.
By its name, buff is likely to be a memory buffer in which to write data, possibly binary data.
There are reasons why one might want to cast it to char *, potentially to use pointer arithmetic on it as one is writing because you cannot do that with a void*.
For example if you are supplied also a size (likely) and your API requires not pointer and size but 2 pointers (begin and end) you will need pointer arithmetic to determine where the end is.
The code could well be C in which case the cast is correct. If the code is C++ though a static_cast is preferable although the C cast is not incorrect in this instance. The reason a static_cast is generally preferred is that the compiler will catch more occasions when you cast incorrectly that way, and it is also more easily greppable. However casting in general breaks type-safety rules and therefore is preferably avoided much of the time. (Not that it is never correct, as it may be here).
Specifically, can it point to int/float etc.?
What about objects like NSString and the like?
Any examples will be greatly appreciated.
void* is such a pointer, that any pointer can be implicitly converted to void*.
For example;
int* p = new int;
void* pv = p; //OK;
p = pv; //Error, the opposite conversion must be explicit in C++ (in C this is OK too)
Also note that pointers to const cannot be converted to void* without a const_cast
E.g.
const int * pc = new const int(4);
void * pv = pc; //Error
const void* pcv = pc; //OK
Hth.
In C any pointer can point to any address in memory, as the type information is in the pointer, not in the target. So an int* is just a pointer to some memory location, which is believed to be an integer. A void* pointer, is just a pointer to a memory location where the type is not defined (could be anything).
Thus any pointer can be cast to void*, but not the other way around, because casting (for example) a void pointer to an int pointer is adding information to it - by performing the cast, you are declaring that the target data is integer, so naturally you have to explicitly say this. The other way around, all you are doing is saying that the int pointer is some kind of pointer, which is fine.
It's probably the same in C++.
A void * can point at any data-like thing in memory, like an integer value, a struct, or whatever.
Do note, however, that you cannot freely convert between void * and function pointers. This is because on some architectures, code is not in the same address space as data, and thus it's possible that address 0x00000000 for code refers to a different set of bits than address 0x00000000 for data does.
It would be possible to implement the compiler so that void * is large enough to remember the difference, but in general I think this is not done, instead the language leaves it undefined.
On typical/mainstream computers, code and data reside in the same address space, and then the compilers typically generate sensible results if you do store a function pointer into a void *, since it can be quite useful.
Besides everything else that was already said by the other users, a void* it's commonly used in callback definitions. This allows your callback to receive user data of any type, including your own defined objects/structs, which should be casted to the appropriate type before using it:
void my_player_cb(int reason, void* data)
{
Player_t* player = (Player_t*)data;
if (reason == END_OF_FILE)
{
if (player->playing)
{
// execute stop(), release allocated resources and
// start() playing the next file on the list
}
}
}
void* can point to an address in memory but the syntax has no type-information. you can cast it to any pointer-type you want but it is your responsibility that that type matches the semantics of the data.
Can someone explain this to me:
char* a;
unsigned char* b;
b = a;
// error: invalid conversion from ‘char*’ to ‘unsigned char*’
b = static_cast<unsigned char*>(a);
// error: invalid static_cast from type ‘char*’ to type ‘unsigned char*’
b = static_cast<unsigned char*>(static_cast<void*>(a));
// everything is fine
What makes the difference between cast 2 and 3? And are there any pitfalls if the approach from 3 is used for other (more complex) types?
[edit]
As some mentioned bad design, etc...
This simple example comes from an image library which gives me the pointer to the image data as char*. Clearly image intensities are always positive so I need to interpret it as unsigned char data.
static_cast<void*> annihilate the purpose of type checking as you say that now it points on "something you don't know the type of". Then the compiler have to trust you and when you say static_cast<unsigned char*> on your new void* then he'll just try to do his job as you ask explicitely.
You'd better use reinterpret_cast<> if you really must use a cast here (as it's obvioulsy showing a design problem here).
Your third approach works because C++ allows a void pointer to be casted to T* via static_cast (and back again) but is more restrictive with other pointer types for safety reasons. char and unsigned char are two distinct types. This calls for a reinterpret_cast.
C++ tries to be a little bit more restrictive to type casting than C, so it doesn't let you convert chars to unsigned chars using static_cast (note that you will lose sign information). However, the type void* is special, as C++ cannot make any assumption for it, and has to rely on the compiler telling it the exact type (hence the third cast works).
As for your second question, of course there are a lot of pitfals on using void*. Usually, you don't have to use it, as the C++ type system, templates, etc. is rich enough to not to have to rely in that "unknown type". Also, if you really need to use it, you have to be very careful with casts to and from void* controlling that types inserted and obtained are really the same (for example, not pointer to subclasses, etc.)
static_cast between pointers works correct only if one of pointers is void or that's casting between objects of classes, where one class is inherited by another.
The difference between 2 and 3 is that in 3, you're explicitly telling the compiler to stop checking you by casting to void*. If the approach from 3 is used for, pretty much anything that isn't a direct primitive integral type, you will invoke undefined behaviour. You may well invoke undefined behaviour in #3 anyway. If it doesn't cast implicitly, it's almost certainly a bad idea unless you really know what's going on, and if you cast a void* back to something that wasn't it's original type, you will get undefined behaviour.
Casts between pointers require reinterpret_cast, with the exception of void*:
Casts from any pointer to to void* are implicit, so you don't need to explicitly cast:
char* pch;
void* p = pch;
Casts from void* to any other pointer only require a static_cast:
unsigned char* pi = static_cast<unsigned char*>(p);
beware, when you cast to void* you lose any type information.
what you are trying to do is incorrect, and false, and error prone and misleading. that's why the compilator returned a compilation error :-)
a simple example
char* pChar = NULL; // you should always initalize your variable when you declare them
unsigned char* pUnsignedChar = NULL; // you should always initalize your variable when you declare them
char aChar = -128;
pChar = &aChar;
pUnsignedChar = static_cast<unsigned char*>(static_cast<void*>(pChar));
then, though pUnsignedChar == pChar nonethless we have *pUnsignedChar == 255 and *pChar == -128.
i do believe this is bad joke, thus bad code.