Home Resource Centre Void Pointer In C | Referencing, Dereferencing & More (+Examples)

Void Pointer In C | Referencing, Dereferencing & More (+Examples)

The pointer is one of the key components of the C programming language. A pointer can be used to hold information about other variables, functions, or even other pointers' memory addresses. Pointers in C programming allow several functional benefits, including low-level memory access and dynamic memory allocation. In this article, we will discuss a specific type of pointer, i.e., the void pointer in C, its uses, limitations, and more.

To begin with, let's get the basics of pointers right. A pointer is a derived data type that may be employed to store a memory location or the address of another C variable. The data stored at that memory location is accessed and modified via pointers.

Syntax Of Pointer

Pointer declarations follow a similar syntax to that of C variable declarations, but we use the (*) dereferencing operator instead.

data_type *ptr_variable;

Here,

  • Data_type: This represents the data type of the variable that the pointer will point to. Any legal C data type, including int, float, char, or even a specially defined data type, can be used.
  • The asterisk (*) indicates that the defined variable is a pointer. It is put before the name of the variable to indicate that it will hold the memory address of another variable.
  • The term ptr_variable identifies the pointer variable. Any legal name for an identifier is acceptable. It is advised to give the pointer a meaningful name that accurately describes its function.

What Is A Void Pointer In C?

A void pointer is a unique type of pointer in the C language that may store the address of any data type. It is declared using the void keyword, which denotes the lack of a specified type attached to the pointer. When the precise data type is unknown or not required, void pointers offer a general method of working with pointers. Interview question

Some key features of void pointers in C programming are:

  • Lack of Type Information: Void pointers in C language are not connected with any type of information. They can point to any sort of object, including user-defined types, floats, characters, and integers. You cannot, however, immediately dereference or use pointer arithmetic on them since the type is unknown.
  • Typecasting: Before dereferencing, the data that a void pointer points to must undergo proper typecasting to the correct type to be used. The compiler may choose the appropriate size and interpretation of the data thanks to typecasting. Incorrect typecasting may result in runtime problems or behavior that is not defined.
  • Versatility: Void pointers in C can be very handy when you need a single pointer to dynamically handle a variety of data types. Without restricting their versatility, they are frequently employed in functions that must receive or return pointers of several types.

Now that we know about the basics of what is a void pointer in C, let's see how to declare these pointers, followed by a proper C code example.

Syntax Of Void Pointer In C:

void *ptr_variable;

Here,

  • void: The void keyword indicates that the pointer does not have a specific data type associated with it. It's employed to declare a general-purpose pointer that may store addresses of any kind.
  • The asterisk (*) indicates that the defined variable is a pointer. It is put before the name of the variable to indicate that it will hold the memory address of another variable.
  • The term ptr_variable identifies the pointer variable. Any legal name for an identifier is acceptable. It is advised to give the pointer a meaningful name that accurately describes its function.

Code Example:

Output:

Value of intValue: 7
Value of floatValue: 3.14
Value of charValue: U

Explanation:

In this simple C program, we begin by including the <stdio.h> header file for essential input/ output operations.

  1. Inside the main function, we declare and initialize three variables of different data types.
  2. These are intValue (integer with the value 7), floatValue (floating-point number with the value 3.14), and charValue (character with the value 'U').
  3. Next, we declare a void pointer ptr (i.e., void *ptr), which can hold the address of any data type.
  4. As mentioned in the code comments, when we assign the addresses of the variables to the void pointers one by one.
  5. First, we assign the pointer variable ptr, the address of the intValue variable, using the address-of/ reference operator.
    • We then use a printf() statement to display the variable's value to the console.
    • Inside the statement, we first typecast the void pointer to the integer pointer using the cast operator, i.e., (int *).
    • Then, we once again use the dereference operator (*) to access the value pointed to by ptr and print it to the console, i.e., *(int *)ptr.
    • We also use the %d format specifier inside the formatted string to indicate integer value and a newline escape sequence to shift the cursor to the next line.
  6. We then reassign ptr with the value of the floatValue variable using the address-of operator (&). Then, we typecast the void pointer to a float pointer and print it to the console using the dereference operator.
  7. Similarly, we assign the address of charValue to ptr, then typecast the pointer to the character pointer and print it to the console using printf() and dereferencing.
  8. Finally, the main() function terminates with a return 0 statement, indicating no errors in execution. 

Time Complexity: O(1)

This example shows that we can access and print the values kept in each corresponding memory location by dereferencing the void pointer with the typecast. To ensure safe memory access and avoid type-related problems, consider that utilizing a void pointer needs careful treatment, including appropriate typecasting.

Note that although void pointers offer flexibility, they should be used with care. To prevent type-related mistakes and guarantee appropriate memory access, it is essential to ensure proper typecasting.

Declaring And Initializing Void Pointer In C With Example

A void pointer in C can be declared and initialized in a variety of ways. We'll look at two typical methods, i.e., declaring a void pointer without initialization and declaring a void pointer with initialization.

Declaring A Void Pointer In C Without Initialization

This method involves merely declaring the pointer variable with the syntax void * type. Here, we do not assign any specific location to the pointer. This is why the process if referred to as defining a void pointer in C without initializing it. It is useful if we want to assign an address at a later time, as we did in the example before.

Syntax:

void *ptr_variable;

Here,

  • A void pointer that may hold the address of any data type is declared by the void pointer declaration.
  • The void pointer variable's name is ptr_variable.
  • Any legal name for an identifier is acceptable.

Take a look at the C code below, which shows how to declare a void pointer in C without initializing it in the same line. 

Code Example: :

Output:

Value of num: 10

Explanation:

In the sample C code-

  1. We define the void pointer named ptr in the main() function after including the standard input/ output library. 
  2. Then, we declare an integer type variable called num and initialize it with the value of 10.
  3. Next, we use the reference operator (&) to assign the address of num to the pointer ptr.
  4. After that, we use the printf() function to print the value of num. For this, we first typecast the void pointer to an integer pointer (int *)ptr to indicate that it points to an integer type data.
  5. Then, we dereference the pointer, i.e., *(int *)ptr, to obtain the value stored at the memory location it points to and print it.
  6. Lastly, the main() function closes with a return 0, indicating successful program execution to the operating system.

Time Complexity : 0(1)

Declaring A Void Pointer In C With Initialization

When defining a void pointer in C programs with initialization, the pointer variable must first be declared with the void keyword and assigned an initial value at the same time using the assignment operator. The initial value can be any variable's address, regardless of its data type, or NULL.

SYNTAX:

void *ptr_variable = NULL;

Here,

  • A void pointer may carry the address of any type of data thanks to the void * declaration.
  • The void pointer variable is referred to as ptr_variable.
  • The void pointer's initial value is set to null via the = NULL operator. The pointer should not point to any specific region in memory until a proper address has been assigned; thus, doing this is a good idea.

Code Example:

Output:

Value of num: 10

Explanation:

In the C code example-

  1. We declare a void pointer called ptr and initialize it with NULL. Here, NULL is a special value representing that the pointer currently does not point to any valid memory location.
  2. Then, we declare an integer variable, num, and initialize it with the value 10.
  3. We then assign the address of the num variable to ptr using the address-of operator(&). Now, ptr points to the memory location where num is stored.
  4. Next, we use a printf() statement to access the num variable using the pointer and print it to the console. 
  5. In the statement, we first typecast the void pointer to an integer pointer, i.e., (int *)ptr to indicate that it points to an integer type data.
  6. Then, we dereference the pointer to access the value stored at that memory location, i.e., *(int *)ptr.

Time Complexity : 0(1)

Complexity:

  • Initializing and declaring a void pointer are straightforward procedures.
  • The actions carried out on the data the void pointer points to determine the complexity.
  • Dereferencing and typecasting void pointers might result in type-related errors if the wrong data type is assumed, which would add to the complexity.

In summary, void pointers in C offer a versatile approach to recording memory locations of any data type. They may be declared by both initializing to NULL and without initialization. When utilizing void pointers, care must be taken to guarantee appropriate typecasting and dereferencing because improper usage may result in undefinable behavior.

How Does The Void Pointer Work In C?

A void pointer in C is a special type of pointer that can hold the address of any data type but does not know the data type it points to. Here's a detailed description of how void pointers work in C:

Step 1: Declaration and Initialization

We first declare a void pointer in C using the void keyword, i.e., void *ptr. A void pointer doesn't know the size or data type of the variable it points to, so it cannot be directly dereferenced. We can also initialize the pointer to NULL (i.e., void *ptr = NULL) to indicate that it currently doesn't point to any valid memory address.

Step 2: Assignment

A void pointer can be assigned the address of variables of any data type, including basic data types (int, float, char), arrays, structs, or even function pointers. For this, we use the reference/ address-of operator (&). When you assign an address to a void pointer, the pointer stores the memory address and effectively forgets about the data type it points to.

Step 3: Typecasting

Before you can use a void pointer to access or manipulate the value it points to, you must first typecast the pointer it to the correct data type. Typecasting has to mostly be done explicitly by specifying the desired data type in parentheses before dereferencing the pointer.

For example, (int *)ptr for an integer, (float *)ptr for a float, (char *)ptr for a character, etc.

It is essential to ensure the void pointer is correctly typecasted to the appropriate data type; otherwise, accessing or manipulating the value could lead to undefined behavior.

Step 4: Dereferencing

After typecasting, you can dereference the void pointer using the indirection operator/ dereferencing operator (*) to access the value stored at the memory location it points to.

For example, if ptr points to an integer variable, you would dereference it as *(int *)ptr, or if it points to a character, you would dereference it as *(char *)ptr.

Common Use Cases Of Void Pointer In C

Unlike other pointers, a void pointer doesn't have a specific data type associated with it. This flexibility makes void pointers useful in various scenarios. Here are some common use cases of void pointers in C:

  • Generic Functions: Void pointers in C are often used in functions that handle different data types. For example, you might have a sorting function that can sort arrays of different data types by accepting a void pointer to the array and another void pointer to a comparison function.

void mySort(void *array, size_t elemSize, size_t arraySize, int (*compare)(const void *, const void *));

  • Dynamic Memory Allocation: Void pointers in C are frequently used in conjunction with dynamic memory allocation functions like malloc(), calloc(), and realloc(). These functions return a void pointer that can be typecasted to the desired data type.

int *intArray = (int*)malloc(5 * sizeof(int));

  • Parameter Passing in Thread Functions: When creating threads using a library like pthreads(), void pointers can be used to pass parameters to the thread function. The thread function can then cast the void pointer in C to the appropriate type.

void* threadFunction(void *arg);

  • File I/O: In functions related to file I/O, void pointers can be used for reading or writing data of different types.

FILE *fp = fopen("example.txt", "r");
void *buffer = malloc(100);

fread(buffer, sizeof(char), 100, fp);

  • Memory Copying: Void pointers in C are useful when copying blocks of memory from one location to another, especially when the data type is not known beforehand.

void* myMemcpy(void *dest, const void *src, size_t n);

Size Of The Void Pointer In C

In C, the size of a void pointer depends on the implementation. It varies depending on the underlying architecture and the particular compiler being used. The platform and the data model, such as 32-bit or 64-bit systems, often determine the size of a pointer.

  • The size of the void pointer on a 16-bit system is 2 bytes.
  • The size of the void pointer on a 32-bit system is 4 bytes.
  • The size of the void pointer on a 64-bit system is 8 bytes.

The sizeof() operator can be used to determine the size of a void pointer in C. Given below is the syntax for the same, followed by a code example.

Syntax For SizeOf Void Pointer In C:

sizeof(void *)

Here,

  • The sizeof() operator returns the operand's size in bytes. It is possible to use it to determine the size of different data types, including pointers.
  • A void pointer type is represented by the void keyword followed by an asterisk (*).

Code Example:

Output:

Size of void pointer: 8 bytes

Explanation:

  1. Inside the main() function of the program, we use the sizeof() on a void pointer to calculate the size.
  2. The expression sizeof(void *) yields a void pointer's size in bytes.
  3. For size_t (the return type of sizeof), we use the printf() function to print the size using the %zu format specifier.
  4. The result displays the void pointer's size, which in this instance is 8 bytes. Depending on the platform and compiler being used, the precise size could change.

Referencing & Dereferencing The Void Pointers In C

In order to operate with pointers in C, including void pointers, one must perform the fundamental procedures of referencing and dereferencing.

Referencing: Obtaining a variable's memory location and assigning it to a pointer is referred to as referencing. Referencing is accomplished using the address-of operator (&).

To reference a variable and assign its address to a pointer, use the following syntax:

data_type *ptr_name;
ptr_name = &variable_name;

Here,

  • The data_type refers to the type of data the pointer, whose name is given by ptr_name, is pointing to.
  • The variable_name indicates the name of the variable whose address is being assigned to the pointer using the reference operator (&).

Dereferencing: Dereferencing a pointer refers to gaining access to the value kept at the memory address the pointer is pointing to. Dereferencing is done with the help of the dereference operator (*).

To dereference a pointer and access the value it points to, use the following syntax:

*ptr_name;

Here, the name of the pointer is given by ptr_name, and it is accessed using the dereference operator (*).

Code Example:

Output:

Value of num using void pointer: 23

Explanation:

  1. Inside the main() function of the program, we declare an integer variable named num that is initialized with the value 23.
  2. We also declare a void pointer called ptr and then assign the address of the num variable to it.
  3. Then, inside the printf() function, we explicitly typecast ptr to an integer pointer using cast operator, i.e., (int *).
  4. After that, we dereference the printer, i.e., *(int *)ptr, to access the value the void pointer points to.
  5. The void pointer is used to read and display the value of num, which results in an output of 23.

Time Complexity: O(1)

Arithmetic Operation On Void Pointers In C

C does not provide arithmetic operations on void pointers. That is, pointer arithmetic is not specified for void pointers in C since they are not connected with a particular data type.

The size of the data type the pointer is pointing to determines how pointer arithmetic works in C. A void pointer cannot be meaningfully added to, subtracted from, incremented, or decremented since its size is unknown, which results in unpredictable behavior.

Code Example:

Output:

Answer: 0x7ffee19aa984

Explanation:

  1. We first declare void pointer ptr in the main() function and then initialize the interger variable num with the value 10.
  2. Next, we assign the void pointer ptr the address of num using the address-of operator (&).
  3. After that, we try to conduct some arithmetic (arithmetic addition) by adding 1 to the void pointer ptr and assigning the outcome to another void pointer result.
  4. The pointer's address is displayed by printing the value of the result using the %p format specifier.

Note- It's crucial to remember that this code generates behavior that is not defined. Since the output value of the result depends on the implementation, it cannot be utilized with confidence.

  • The conventions of pointer arithmetic are violated and broken when operations are performed on void pointers in C.
  • The void pointer in C has to be typecasted to a specified pointer type to specify the size of the data type it points to before performing legal pointer arithmetic.
  • After that, the typed pointer may be used for mathematical operations.

In conclusion, C prohibits the use of arithmetic operations on void pointers. Void pointers must be typecast to a specific pointer type before being used for arithmetic operations, mostly for general pointer storage.

Why And When To Use Void Pointers In C?

Void pointers in C are employed when it's necessary to write generic C code that may operate on a variety of data types without being bound to a particular type. Here are several situations and justifications for using void pointers in C:

  • Generic Interfaces: The use of void pointers in C makes it possible to build APIs, data structures, and functions that can work with many data types. This is helpful if you want to create adaptable code that can work with different types of data without requiring numerous versions.
  • Memory Management: Void pointers in C can be utilized in situations when you need to dynamically allocate and deallocate memory for various kinds of data. Writing general memory management procedures that operate with any form of data is possible by utilizing void pointers.
  • Data Structures: Void pointers in C may be used to create data structures, such as linked lists or binary trees, that can handle and store many sorts of components. More flexible and reusable programming is now possible.
  • Callback Functions: When sending function pointers as parameters to other functions, callback functions frequently utilize void pointers. This enables the called function to call the callback function even when it isn't aware of the precise function signature or data types involved.

Void Pointer In C Example 1- Generic Printf() Function & Void Pointer To Access Variables

Code Example:

Output:

Integer value: 23
Float value: 3.14
Character value: M

Explanation:

In this example C program-

  1. We start by defining a function called printValue to print the value of a variable whose address is passed to a void pointer, along with a character representing the data type.
  2. Inside the function, we use a switch-case statement that checks the variable's data type, provided by the dataType character, and implements the case dependent on that.
    • For the case i (integer), the function prints the integer value using printf and typecasts the void* pointer to an int*.
    • For the case f (float), the function prints the float value with two decimal places using printf and typecasts the void* pointer to a float*.
    • For case c (character), the function prints the character value using printf and typecasts the void* pointer to a char*.
    • If none of the specified cases match, the function prints "Invalid data type."
    • The break and continue statements ensure that the flow continues if the case is not met, and exits the switch statement once a case has been implemented. 
  3. Then, in the main() function, we declare and initialize three variables (intValue, floatValue, and charValue) with different values.
  4. Next, we call the printValue function three times with the addresses of these variables and their corresponding data type characters ('i', 'f', 'c').
  5. This way we can access the variables stored in the void pointer and print it to the console.
  6. The program returns 0 to the operating system, indicating successful execution.

Void Pointer In C Example 2- Generic Dynamic Memory Allocation 

Code Example: 

Output:

Value of intPtr: 23
Value of floatPtr: 3.14

Explanation:

We begin the example by including essential header files for dynamic memory allocation and deallocation, i.e., <stdlib.h> and <stdio.h> for input/ output operations.

  1. We then define a function allocateMemory, which takes a size_t parameter, dynamically allocates memory using malloc based on the specified size, and returns a void* pointer.
  2. Then, we define another function, deallocateMemory, that takes a void* pointer, representing the allocated memory, and frees it using the free function.
  3. Inside the main() function, memory is then dynamically allocated for an integer (intPtr) and a float (floatPtr) using the allocateMemory function.
  4. Next, we assign values (23 for intPtr and 3.14 for floatPtr) to the allocated memory locations using dereferencing.
  5. We then print the values stored in the allocated memory to the console using the printf() function.
  6. Lastly, we deallocate the memory allocated for both pointers using the deallocateMemory() function to prevent memory leaks.
  7. Finally, the program returns 0 to the operating system, indicating successful execution.

Limitations Of Void Pointer In C

Void pointers in C give programmers freedom and genericity in writing concise and efficient programs. But they also have several restrictions. Here are some drawbacks of the void pointers in C:

  • No Type Safety: Since void pointers can point to any data type, they are not type-safe. This implies that type checking cannot be performed at compile time by the compiler, and therefore, incorrect use or typecasting of void pointers in C may result in runtime errors or unpredictable behavior.
  • Need for Explicit Typecasting: The use of a void pointer in C necessitates explicit typecasting in order to correctly access the data it links to. If the typecasting is done incorrectly, this adds a degree of complexity and the opportunity for mistakes.
  • No Pointer Arithmetic: Pointer arithmetic operations like addition, subtraction, and increment/decrement cannot be performed on void pointers. Pointer arithmetic is useless since it depends on the size of the data type, which is unknown for a void pointer in C.
  • Limited Compile-Time Checking: Errors related to memory access or type mismatch may not be caught at compile-time because void pointers in C can carry any address, even incorrect addresses. Debugging becomes more difficult because these mistakes might not be discovered until runtime.
  • Lack of Size Information: These pointers do not retain the size of the data they point to. Due to this, it may be challenging to calculate the amount of the data to carry out activities, such as copying or comparing data, that depend on size.
  • Increased Possibility of Glitch: The adaptability of void pointers in C raises the possibility of glitches and difficult-to-detect mistakes. Without the appropriate typecasting and checks, it is easier to introduce errors and inconsistencies into the code.

Advantages of Void Pointer In C

The following are the benefits of void pointers in C:

  • Flexibility and Generality: Void pointers give programmers a method to write code that isn't bound to any one data type and can handle a variety of data types. They increase the adaptability and reuse of code by enabling the development of functions, data structures, and APIs that can work with different forms of data.
  • Dynamic Memory Management: Void pointers in C are frequently employed in situations involving dynamic memory allocation functions. They enable the assignment and release of memory blocks of various sizes and kinds of data. When working with data structures that can contain elements of various kinds or when the extent of the allocated RAM is decided at runtime, this flexibility is very helpful.
  • Function Pointers and Callbacks: The void pointers in C are also employed when working with function pointers and constructing callback systems. They make it possible to build generic callback functions that can take multiple kinds of function pointers, giving you a means to dynamically handle diverse activities or events.
  • Compatibility with Outside Libraries: Void pointers in C make it easier for external libraries or APIs that use opaque types or have variable return types to communicate with each other. They act as a link between C code and libraries made in other languages by enabling the transfer of generic data to and from other functions.
  • Interfaces that are independent of data type: Void pointers in C make it possible to create interfaces that are independent of data type and may be utilized by a variety of modules or components. By separating the interface from specific implementation details, this abstraction supports modularity and encapsulation.
  • Effective Memory Allocation: Void pointers in C can be used to allocate memory blocks of various sizes, increasing the effectiveness and efficiency of memory allocation. They make it possible for memory allocation algorithms to be more flexible, particularly when working with a variety of data types or variable-sized structures.
  • Reduced Compilation Dependencies: Void pointers in C might minimize the compilation's reliance on certain data types. This might be advantageous when working with complicated or big codebases since it enables the decoupling of certain modules or functions from particular data types, lowering compile-time dependencies and accelerating build times.

Key Points To Remember

The following are some significant one must remember when working with a void pointer in C:

  • Typeless Pointer: A void pointer can also be referred to as a typeless pointer in C. The fact that it can store the address of any data type enables generic programming.
  • Typecasting: Before dereferencing or executing operations on the data they point to, void pointers in C must be explicitly typecast to the correct data type. This is essential due to the compiler's lack of knowledge regarding a void pointer's underlying data type.
  • Lack of Size Information: These pointers do not retain the size of the data they point to. Because of this, it's crucial to explicitly handle the size when using these pointers in operations like copying or comparing data.
  • Passing Void Pointers as Function Arguments: The void pointers in C are frequently used as function pointers when sending generic data or objects to functions. As a result, functions may operate on several data types without requiring unique implementations for each type.
  • Pointer arithmetic: Void pointers in C cannot be used for arithmetic operations like addition, subtraction, increment, or decrement. Pointer arithmetic is useless for void pointers since they have an unknown size.
  • Handling of Invalid Memory Access: Given that a void pointer in C is capable of storing any address, including invalid or uninitialized addresses, it is crucial to take care of any issues that can occur while reading or changing the data referred to by a void pointer.
  • Type Safety Considerations: Void pointers cause a loss of type safety since they enable generic programming; hence, they should be avoided. To prevent such issues, it is essential to handle void pointers carefully, guarantee appropriate typecasting, and carry out the necessary runtime checks.
  • Portability: These pointers are portable across several systems and compilers because of the standardized behavior of void pointers in C. When working with void pointers, it's crucial to be aware of any unique platform or compiler restrictions.

Conclusion

Void pointers in C language are an effective tool for handling generic data and building flexible, reusable programs. They enable the creation of generic interfaces, data structures, and functions that can operate on a number of data types and are not constrained to a particular type. Void pointers are used to efficiently manage dynamic memory, interact with third-party libraries, and allocate memory.

However, it is essential to handle them cautiously since void pointers in C lack type safety and call for explicit typecasting. Proper usage is essential to preventing errors and erratic behaviors. Dereferencing, typecasting, and managing memory allocation and deallocation are all included. Knowing the advantages, limitations, and best practices of void pointers may help developers construct C programs that are more adaptive and versatile.

Frequently Asked Questions

Q. What are void pointers and null pointers in C?

Void Pointer: A void pointer in C, denoted by the symbol void *, is a particular kind of pointer that may store the address of any type of data. It is a general-purpose pointer without a defined data type. The void pointer is largely used to achieve flexibility and generality in code, enabling the development of functions and data structures that are not restricted to a single data type and may operate on a variety of data types. When dereferencing or executing operations on the data it links to, explicit typecasting is necessary since the void pointer in C lacks type information.

Example:

Output:

Value of intValue: 42
Value of floatValue: 3.140000
Value of charValue: A

Null Pointer: A null pointer is a specific value that can be applied to a pointer variable to show that it does not point to any usable memory locations. It signifies the absence of a correct address. The literal constant NULL, which is commonly defined as (void *)0, is how the null pointer is represented in C. Null pointers are frequently employed to initialize pointers, check for faulty or uninitialized pointers, or signify the conclusion of specific data structures.

Example:

Output:
ptr is a null pointer.

Q. What is pointer dereferencing in C?

In C, pointer dereferencing refers to accessing the value held at the memory address that the pointer is pointing to. The dereference operator (*) is used to do this. Dereferencing a pointer allows you to access or change the data kept at the memory address the pointer is pointing to.

Q. What is the void * pointer function?

An operation that utilizes or returns a void pointer is referred to as a void * pointer function. The function may handle various data types with more flexibility as a result. By employing void pointers as function parameters or return types, such functions are capable of working with a variety of data types. The use of void pointers within functions, however, frequently necessitates explicit typecasting before dereferencing or executing actions on the data.

Q. What are dangling pointers in C?

D/inter: In the C programming language, a dangling pointer is a pointer that directs the user to an invalid or deallocated memory address. Usually, it happens when a pointer is released or when a function delivers a pointer to a local variable that exits the scope of the function. When dereferenced, dangling pointers may behave in an undefinable way.

Example:

Output:

Value at ptr: 10

Q. What is a double pointer in C?

A double pointer, usually referred to as a pointer to a pointer, is a specific kind of pointer that stores the address of another pointer variable. Dynamic data structures like pointer arrays, linked lists, and multi-dimensional arrays may be created and modified using this technique. In situations when pointers are sent by reference or when working with dynamically allocated memory, double pointers offer an additional degree of indirection.

Example:

Output:

Value at ptr: 42

Q. What is an indirection operator in C?

The indirection operator, indicated by placing a pointer variable name right after it with no space in between, is a tool that helps fetch the value stored in the memory location pointed by a pointer variable.

Example:

Output:

Value of 'num' : 42

Code explanation: In this example, ptr is a pointer variable pointing to the memory location of the integer variable num. The *ptr expression, using the indirection operator (*), allows us to retrieve and print the value stored at that memory location, which is 42 in this case.

Q. What is the difference between void and void pointer?

The void keyword can be used both to create void pointers in C as well as to create other elements like functions that are of void type. The table below lists the difference between the void keyword and the void pointer in C. 

Feature void void pointer (void*)
Basic Usage Used as a return type for functions that do not return a value. Used as a generic pointer type that can point to objects of any type.
Data Type Not a data type. Represents the absence of a specific type. Not a data type. Represents a generic pointer type.
Pointer Type Not a pointer type. A pointer type that can point to objects of any data type.
Pointer Arithmetic Not applicable. It supports pointer arithmetic since it's a generic pointer type.
Dereferencing Not applicable. It cannot be dereferenced. It can be dereferenced but requires explicit typecasting to access the value of the pointed object.
Type Safety N/A Requires careful typecasting to ensure correct interpretation of the data when dereferencing. Lacks compile-time type checking.
Common Use Case Used in function declarations to indicate no return value. Used when a pointer needs to refer to an unspecified data type, common in generic programming scenarios.
Example void myFunction() {
// Function with no return value
// ...
}

void* genericPointer;

int integerValue = 42;
float floatValue = 3.14;

// Using void* to create a generic pointer
genericPointer = &integerValue;
printf("Integer Value: %d\n", *(int*)genericPointer);

genericPointer = &floatValue;
printf("Float Value: %.2f\n", *(float*)genericPointer);

Q. What is the difference between a specific pointer and a void pointer in C?

Void pointers (void*) and specific pointers (pointers to a specific data type) have distinct characteristics and use cases in C programming.

A void pointer in C (void*) is a general-purpose pointer with no specific data type associated with it. It can be used to store the address of any data type.

  • The flexibility of void pointers allows for generic programming, especially in situations where the data type is not known beforehand or needs to be determined dynamically at runtime.
  • However, using void pointers requires careful typecasting when dereferencing to ensure proper interpretation of the data.

A specific pointer, on the other hand, is a pointer that is explicitly defined to point to a particular data type. For example, a pointer declared as int* is meant to store the address of an integer variable, and it can only be used to point to integer values.

  • Specific pointers provide type safety and allow the compiler to perform type-checking during compilation, catching potential errors at an earlier stage.
  • This specificity comes at the cost of reduced flexibility compared to void pointers.

Enjoyed reading about void pointers in C? Here are a few other curated pieces on important programming fundamentals you must know:

  1. Logical Operators In C Explained (Types With Examples)
  2. Control Statements In C | The Beginner's Guide (With Examples)
  3. Comma Operator In C | Code Examples For Both Separator & Operator
  4. Jump Statement In C | Types, Best Practices & More (+Examples)
  5. Tokens In C | A Complete Guide To 7 Token Types (With Examples)
Shivani Goyal
Manager, Content

I am an economics graduate using my qualifications and life skills to observe & absorb what life has to offer. A strong believer in 'Don't die before you are dead' philosophy, at Unstop I am producing content that resonates and enables you to be #Unstoppable. When I don't have to be presentable for the job, I'd be elbow deep in paint/ pencil residue, immersed in a good read or socializing in the flesh.

TAGS
Engineering Computer Science
Updated On: 1 Mar'24, 10:21 AM IST