why trying to deference void pointer does not work? - c

int main()
{
int b = 12;
void *ptr = &b;
printf("%d", *ptr);
return 0;
}
I expected for this code to print 12, but it does not.
if instead of void pointer, we define int pointer it would work.
I wanted to know how can we use void pointer and print the address allocated to it and the amount saved in it?

Dereferencing a void * doesn't make sense because it has no way of knowing the type of the memory it points to.
You would need to cast to pointer to a int * and then dereference it.
printf("%d", *((int *)ptr));

void pointers cannot be dereferenced.it will give this warning
Compiler Error: 'void' is not a pointer-to-object type*
so, you have to do it like this.
#include<stdio.h>
int main()
{
int b = 12;
void *ptr = &b;
printf("%d", *(int *)ptr);
return 0;
}

If p has type void *, then the expression *p has type void, which means "no value". You can't pass a void expression to printf for the %d conversion specifier (or any other conversion specifier).
In order to dereference a void *, you must first convert it to a pointer of the appropriate type. You can do it with a cast:
printf( "%d\n", *(int *) ptr );
or assign it to a pointer of the appropriate type:
int *p = ptr;
printf( "%d\n", *p );
The rules around void pointers are special such that they can be assigned to other pointer types without an explicit cast - this allows them to be used as a "generic" pointer type. However, you cannot directly examine the thing a void pointer points to.

A schoolbook example of when void pointers are useful is qsort.
This is the signature:
void qsort(void *base,
size_t nitems,
size_t size,
int (*compar)(const void *, const void*)
);
base is just a pointer to the first element. The reason it's a void pointer is because qsort can be used for any list, regardless of type. nitems is number of items (doh) in the list, and size is the size of each element. Nothing strange so far.
But it does also take a fourth argument, which is a function pointer. You're supposed to write a custom compare function and pass a pointer to this function. This is what makes qsort able to sort any list. But since it's supposed to be generic, it takes two void pointers as argument. Here is an example of such a compare function, which is a bit bloated for clarity:
int cmpfloat(const void *a, const void *b) {
const float *aa = (float*) a;
const float *bb = (float*) b;
if(*aa == *bb) {
return 0;
} else if(*aa > *bb) {
return 1;
} else {
return -1;
}
}
Pretty clear what is going on. It returns positive number if a>b, zero if they are equal and negative if b>a, which is the requirements. In reality, I'd just write it like this:
int cmpfloat(const void *a, const void *b) {
return *(float*)a - *(float*)b;
}
What you do with this is something like:
float arr[5] = {5.1, 3.4, 8.9, 3.4, 1.3};
qsort(arr, 5, sizeof *arr, cmpfloat);
Maybe it's not completely accurate to say that void pointers are used instead of templates, generic functions, overloaded functions and such, but they have similarities.

Related

converting a string to a void pointer

I'm trying to figure out how to "transform" strings (char*) to void* and viceversa.
When I execute this my output is just the first printf and ignores the second one, it doesn't even write "after = "
PS This little program is just to understand, I know i could actually use swap(&s[0],&s[1]). I need to know how to properly cast a void pointer into an array of strings.
I'm working on a uni project where I need to create my own quick_sort algorythm and I need the swap function inside of it to work with void pointers.
#include <stdio.h>
#include <stdlib.h>
static void swap(char** x,char** y);
static void swap(char** x,char** y){
char* temp=*x;
*x=*y;
*y=temp;
}
int main()
{
char* s[2];
s[0]="weee";
s[1]="yooo";
void* array=s;
printf("before %s %s\n",s[0],s[1]);
swap((&array)[0],(&array)[1]);
printf("after = %s %s",(char*)array,(char*)array);
return 0;
}
I think I'm missing something big
Thanks in advance :D
In this declaration the array s used as an initializer is implicitly converted to a pointer to its first element of the type char **.
void* array = s;
In the call of the function swap
swap((&array)[0],(&array)[1]);
the first argument can be the pointer array itself that will be implicitly casted to the pointer type of the corresponding parameter
swap( array, (&array)[1]);
But you need to correctly pass the second argument. To do this you need to cast the pointer array explicitly like
swap( array, ( char ** )array + 1 );
In the call of printf you need also correctly to supply argument expressions.
Here is your updated program
#include <stdio.h>
static void swap(char** x,char** y);
static void swap(char** x,char** y){
char* temp=*x;
*x=*y;
*y=temp;
}
int main()
{
char* s[2];
s[0]="weee";
s[1]="yooo";
void* array=s;
printf("before %s %s\n",s[0],s[1]);
swap( array, ( char ** )array + 1 );
printf("after = %s %s", *(char**)array, ( (char**)array )[1]);
return 0;
}
The program output is
before weee yooo
after = yooo weee
void *array = s; declares array to be a void *. Then &array is the address of that void *, so &array[1] would access a void * after it. But there is no void * after it, since void *array defines a single void *.
array could be properly defined to alias s with char **array = s;, after which swap(&array[0], &array[1]); would work as desired.
If you define array as void **array = (void **) s;, then swap(&array[0], &array[1]); will produce diagnostic messages because the types are wrong. You could use swap((char **) &array[0], (char **) &array[1]);.
Then, if you print the strings with printf("after = %s %s", array[0], array[1]);, this will work, although it is not entirely proper code. Using array[0] as an argument passes a void * where printf is expecting a char * for the %s. However, the C standard guarantees that void * and char * have the same representation (encode their values using bytes in memory in the same way), and it further says (in a non-normative note) that this is intended to imply interchangeability as arguments to functions.
The void* doesn't seem to fulfil any particular purpose here, just swap the pointers: swap(&s[0],&s[1]);.
You could also do this:
char** ptr = &s[0];
printf("before %s %s\n",ptr[0],ptr[1]);
swap(&ptr[0],&ptr[1]);
printf("after = %s %s",ptr[0],ptr[1]);
If you for reasons unknown insist on using void* then note that as your code stands, it points at the first char* in your array of char*. However, it isn't possible to perform pointer arithmetic on void* since that would entail knowing how large a "void" is. The void* doesn't know that it points at an array of pointers. Therefore array[i] is nonsense.
Also, the void* are set to point at char* so you simply cannot pass it to a function expecting a char**. You'd have to rewrite the whole program in a needlessly obfuscated way, so just abandon that idea.

Converting a int pointer to a void pointer and back to use the value in another function?

I would like to convert a int pointer to a void pointer and pass that void pointer to a function and then back to an int pointer to use that value in another function.
void main(){
int newSize = size;
void *newSizePtr = &newSize;
someFunc(newSizePtr);
}
void someFunc(void *newSizePtr){
int actualValue = *((int *) newSizePtr);
}
Is this the right way to convert a int ptr to a void ptr and then back to use the value?
i am unable to dynamically allocate memory to the pointer itself because of restrictions with my program that i cannot use malloc. i.e.
int *newSize = malloc(sizeof(int));
which is why i did it this way.
i also need to pass in a void* argument because in my program i am using pthread_create(). This function requires me to pass in an argument of a void* to the function which is why i casted it to a void* and then back when i needed to use it
The conversion you are doing is explicitly allowed by the C standard. Section 6.3.2.3p1 regarding pointer conversions states:
A pointer to void may be converted to or from a pointer to any
object type. A pointer toa ny object type may be converted to a
pointer to void and back again; the result shall compare equal
to the original pointer.
It's also not necessary to explictily cast to or from a void *. So you can do something like this:
void someFunc(void *newSizePtr){
int *actualValuePtr = newSizePtr;
}
int main(){
int newSize = size;
pthread_t tid;
pthread_create(&tid, NULL, someFunc, &newSize);
}
#include <stdio.h>
#include <memory>
void someFunc(void*);
int main() {
int size = 4;
int newSize = size;
void* newSizePtr = &newSize;
someFunc(newSizePtr);
// void* -> int*, before using
int* newSize = (int*) malloc(sizeof(int));
}
void someFunc(void* newSizePtr) {
int actualValue = *((int*)newSizePtr);
printf("%d", actualValue);
}
Yes you can cast void* to int*, and int* to void *,
Because, void * is 'generic' pointer.
malloc returns generic pointer (void*) because malloc does not know what 'type' of return you need.
So, you need to convert to the type you need.
(In the above code, you need to convert to void* -> int*)
For more information about usage of generic pointer, below link may help you
https://codexpart.com/what-is-generic-pointer-difference-between-generic-pointer-and-void-pointer/

C Programming- Pointers

I came across the following code, the output for which is 0.
Is the statement vptr = &i correct? Can we assign a void pointer, address of an integer variable?
#include<stdio.h>
void fun(void *p);
int i;
int main()
{
void *vptr;
vptr = &i;
fun(vptr);
return 0;
}
void fun(void *p)
{
int **q;
q = (int**)&p;
printf("%d\n", **q);
}
The statement vptr = &i; is fine.
However, the statement q = (int**)&p; is incorrect. &p does not point at an int*, it points at a void*. It is not guaranteed that int* and void* have compatible layouts.
A correct implementation of fun would be
void fun(void *p)
{
printf("%d\n", *(int*)p);
}
Any pointer type can be converted into void*.
From the C standard 6.3.2.3p1:
A pointer to void may be converted to or from a pointer to any object
type. A pointer to any object type may be converted to a pointer to
void and back again; the result shall compare equal to the original
pointer.

Understanding void pointers and typedef pointer functions

I am trying to learn about void pointers and functions that have a typedef (in C). I can't seem to grasp the concept.
I have this simple code:
#include <stdio.h>
typedef int (*CompareFunc)(void*, void*);
int compareints(void *a, void *b)
{
return a-b;
}
int comparedbls(void *a, void *b)
{
return a-b;
}
int main()
{
int a = 1, b = 1;
int* ptrA = &a;
int* ptrB = &b;
CompareFunc test = compareints;
printf("%d\n", test(ptrA, ptrB));
return 0;
}
The output here is "-4". I don't understand why. I know it's some kind of casting that I'm not doing because I feel like I am subtracting addresses. I would print the values of void *a and void *b with printf("%d", a) to see what values they have, but it says it can't because a is a void pointer.
And with the CompareFunc function, would I have to make a new variable to point to every function I want? I am not quite sure in what case using a typedef on a pointer function would ever be useful. Why not just call compareints() directly? Asking because I have an assignment and can't figure out why we need to code it like this.
Any help would be appreciated. Thank you!
compareints() returns the difference between two pointers, whether that was your intention or not. If not, you may want to try this:
int compareints(void *a, void *b)
{
return *(int *)a - *(int *)b;
}
and this:
double comparedbls(void *a, void *b)
{
return *(double *)a - *(double *)b;
}
The value resulting from how you called it is implementation defined, however, because local variables can be arranged on the stack in any order.
with the CompareFunc function, would I have to make a new variable to point to every function I want?
No. A function pointer can point to any function with the same signature as the pointer.
Typedefs of function pointers can be handy, for example, if you need to pass a comparison function to a generic sort algorithm. In your instance, function pointers are completely unnecessary.
As for casting, any pointer type is allowed to be implicitly converted into a void *, and vice versa. This is done when you call compareints(). When subtracting two pointers of the same type, a value of type ptrdiff_t is returned, which is then implicitly converted into an int when returned from compareints().
int compareints(void *a, void *b)
{
return a-b;
}
This returns difference between two pointers a and b .What value you get is however , implementation defined .
To get difference between their values you can do this -
int compareints(void *a, void *b)
{
return *(int *)a-*(int *)b;
}

What does the declaration void** mean in the C language?

I'm beginning to learn C and read following code:
public void** list_to_array(List* thiz){
int size = list_size(thiz);
void **array = malloc2(sizeof(void *) * size);
int i=0;
list_rewind(thiz);
for(i=0; i<size; i++){
array[i] = list_next(thiz);
}
list_rewind(thiz);
return array;
}
I don't understand the meaning of void**. Could someone explain it with some examples?
void** is a pointer to a pointer to void (unspecified type). It means that the variable (memory location) contains an address to a memory location, that contains an address to another memory location, and what is stored there is not specified. In this question's case it is a pointer to an array of void* pointers.
Sidenote: A void pointer can't be dereferenced, but a void** can.
void *a[100];
void **aa = a;
By doing this one should be able to do e.g. aa[17] to get at the 18th element of the array a.
To understand such declarations you can use this tool and might as well check a related question or two.
void** is a pointer to void*, or a pointer to a void pointer if you prefer!
This notation is traditionally used in C to implement a matrix, for example. So, in the matrix case, that would be a pointer to an array of pointers.
Normally void * pointers are used to denote a pointer to an unknown data type. In this case your function returns an array of such pointers thus the double star.
In C, a pointer is often used to reference an array. Eg the following assignment is perfectly legal:
char str1[10];
char *str2 = str1;
Now when void is used, it means that instead of char you have a variable of unknown type.
Pointers to an unknown data type are useful for writing generic algorithms. Eg. the qsort function in standard C library is defined as:
void qsort ( void * base,
size_t num,
size_t size,
int ( * comparator )
( const void *, const void * ) );
The sorting algorithm itself is generic, but has no knowledge of the contents of the data. Thus the user has to provide an implementation of a comparator that can deal with it. The algorithm will call the comparator with two pointers to the elements to be compared. These pointers are of void * type, because there is now information about the type of data being sorted.
Take a look at this thread for more examples
http://forums.fedoraforum.org/showthread.php?t=138213
void pointers are used to hold address of any data type. void** means pointer to void pointer. Void pointers are used in a place where we want a function should receive different types of data as function argument. Please check the below example
void func_for_int(void *int_arg)
{
int *ptr = (int *)int_arg;
//some code
}
void func_for_char(void *char_arg)
{
char *ptr = (char *)char_arg;
//some code
}
int common_func(void * arg, void (*func)(void *arg))
{
func(arg);
}
int main()
{
int a = 10;
char b = 5;
common_func((void *)&a, func_for_int);
common_func((void *)&b, func_for_char);
return 0;
}

Resources