The void pointer is used in C as a kind of generic pointer. The void pointer variable can be used to contain the address of any type of variable. The problem with the void pointer is that when you assigned an address to the pointer, the variable type information is no longer available to the compiler for verification.
In general, void pointers should be avoided, since the type of the variable whose address is in the void pointer is no longer available to the compiler. On the other hand, there are cases when the void pointer is very convenient. However, the programmer needs to know the type of variable whose address is in the void pointer variable and use it correctly.
Much of the C source code has a C-style created between type pointers and void pointers. This is not necessary for modern compilers, and should be avoided.
The size of the void pointer variable is known. The size of the variable whose pointer is in the void pointer variable is unknown. For example, here are some initial examples.
// create several different kinds of variables int iValue; char aszString[6]; float fValue; int *pIvalue = &iValue; void *pVoid = 0; int iSize = sizeof(*pIvalue); // get size of what int pointer points to, an int int vSize = sizeof(*pVoid); // compile error, size of what void pointer points to is unknown int vSizeVar = sizeof(pVoid); // compiles fine size of void pointer is known pVoid = &iValue; // put the address of iValue into the void pointer variable pVoid = &aszString[0]; // put the address of char string into the void pointer variable pVoid = &fValue; // put the address of float into the void pointer variable pIvalue = &fValue; // compiler error, address of float into int pointer not allowed
One way to use void pointers is to have several different types of structures that are provided as arguments to a function, usually some kind of dispatch function. Since the interface for the function allows different types of pointers, the void pointer must be used in the argument list. Then the type of the variable pointed to is determined either by an additional argument, or checks the specified variable. An example of such a use of a function is the following. In this case, we include a pointer to the type of structure in the first member of the various permutations of the structure. As long as all the structures that are used with this function have as their first member an int
indicating the type of structure, this will work.
struct struct_1 { int iClass; // struct type indicator. must always be first member of struct int iValue; }; struct struct_2 { int iClass; // struct type indicator. must always be first member of struct float fValue; }; void func2 (void *pStruct) { struct struct_1 *pStruct_1 = pStruct; struct struct_2 *pStruct_2 = pStruct; switch (pStruct_1->iClass) // this works because a struct is a kind of template or pattern for a memory location { case 1: // do things with pStruct_1 break; case 2: // do things with pStruct_2 break; default: break; } } void xfunc (void) { struct struct_1 myStruct_1 = {1, 37}; struct struct_2 myStruct_2 = {2, 755.37f}; func2 (&myStruct_1); func2 (&myStruct_2); }
Something like the above has a number of problems with the design of communication and communication software, so if you have no good reason to use this approach, it is better to rethink your design. However, the C programming language allows you to do this.
There are some cases where a void pointer is required. For example, the malloc()
function, which allocates memory, returns a void pointer containing the address of the region that was allocated (or NULL if the allocation fails). The void pointer in this case allows you to use one malloc()
function, which can return the memory address for any type of variable. The following shows the use of malloc()
with various types of variables.
void yfunc (void) { int *pIvalue = malloc(sizeof(int)); char *paszStr = malloc(sizeof(char)*32); struct struct_1 *pStruct_1 = malloc (sizeof(*pStruct_1)); struct struct_2 *pStruct_2Array = malloc (sizeof(*pStruct_2Array)*21); pStruct_1->iClass = 1; pStruct_1->iValue = 23; func2(pStruct_1);