void * assignment to void ** - c

Need to implement one api which has some parameters;which has input's type (const void*), output's type (void**); the api wants to assign input with some offset to the output; for example,
void getOffset(const void* a, void** b)
{
int offset = getsomeoffset();
*b = a + offset;
}
This will have some complain in the compiler. What's the correct way to write this code? The input's type can be float, int, double.

You cannot apply pointer arithmetics on a void * pointer. The target pointed to does not have any type and hence no size which could be used to calculate the offset.
Therefore you need to cast your pointer before applying the offset:
*b = ((char *)a) + offset;
With this statement the offset is interpreted as number of bytes.

The problem here is the offset. A void has no size, so C does not allow pointer arithmetics on void *. Assuming that you want to use byte addresses, you should pass through char * arithmetics:
void getOffset(const void* a, void** b)
{
int offset = getsomeoffset();
char *p = a; // automatic conversion from void * to char *
p += offset; // char pointer arithmetics
*b = p; // automatic conversion for char * to void *
// or directly: *b = ((char *) a) + offset;
}

Given void *a, a + offset violates 6.5.6 Additive operators, paragraph 8 of the C standard:
When an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough...
A void * doesn't have a type, and it can't point to an actual object.
As others have noted, you have to cast the void * to another type, most likely char * would be appropriate.

Related

why trying to deference void pointer does not work?

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.

Some misunderstand about casting in generic function

I have some misunderstanding of the tutorial from my class. There is function called print_Arr(), it's generic function that gets pointer to arrays of double or integers and prints it.
Here is the code:
int main() {
int a[] = { 2,7,6,4,1 };
double b[] = { 12.5,2.7,3.0,5.5,5.9,1.0 };
print_Arr(a, sizeof(a)/sizeof(a[0]), sizeof(int), print_int);
print_Arr(b, sizeof(b)/sizeof(b[0]), sizeof(double), print_double);
}
void print_Arr(void* a, int size, int m, void (*print_func)(void* )) {
for (int i = 0; i <= size-1; i++)
{
print_func((char*)a + m*i);
}
}
void print_int(int* p) {
printf("%d\n", *p);
}
void print_double(double* num) {
printf("%f\n", *num);
}
Why do I have to make cast a to (char*) in this row:
print_func((char*)a + m*i);
I sent to print_Arr() generic function two type of arrays integers or doubles,
thus it is logically to cast a to int * or to double*.
But why is it casted to char*? What do I miss?
First, a word on why the cast is needed:
Pointer arithmetic makes use of the size of the type being pointed to. void is a forever incomplete type, that cannot be completed, so pointer arithmetic is not possible on a pointer to void type.
To add, for the additive operators, quoting from C11, chapter §6.5.6, constraints:
For addition, either both operands shall have arithmetic type, or one operand shall be a
pointer to a complete object type and the other shall have integer type.
and, from chapter §6.2.5,
The void type comprises an empty set of values; it is an incomplete object type that
cannot be completed.
That said, why the cast is to char* :
Pointer arithmetic makes use of the type being pointed to. Quoting the spec once again
[...] if the expression P points to
the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and
(P)-N (where N has the value n) point to, respectively, the i+n-th and i−n-th elements of
the array object, provided they exist.
Here, look at your construct:
((char*)a + m*i);
where m is the size of the actual object type pointed to by the actual argument. So, if you cast the pointer to the actual type, the calculation would be wrong. To present a comparison, say:
sizeof (char) is 1, mandated by standard.
sizeof (int) == 4 , say in your platform.
So, for an array int arr[ ] = {1, 2, 3, 4}, the expressions
(char*)a + (sizeof(int)*1)
and
(int*) a + 1
are equivalent.
Finally, touching the topic of converting another type of pointer to char* and accessing it:
[...] When a pointer to an object is converted to a pointer to a character type,
the result points to the lowest addressed byte of the object. Successive increments of the
result, up to the size of the object, yield pointers to the remaining bytes of the object. [....]
You need the char * cast because you do pointer arithmetic on the pointer, to get a byte offset from the beginning, but you can't do that on a void *.
A void pointer doesn't have a type size, so you can't calculate with it.
public:
int num=0;
int c;
int doubleToChar(double a){
while ((a-1)>=0){
num++;
}
c=a;
return a*10;
}/* int doubleToCharhundred(double a){
while ((a-1)>=0){
num++;
}
return a*100-c;
}*/
double a=12.12345;
char *tenDivide ;
char *intPart;
//u can add hundred or thousand by another char;
tenDivide =doubleToChar(a);
if(num<128)
intPart=num;
else{
while(num-1){
//same doubleToChar
}
}

Swap function using void pointers [duplicate]

This question already has answers here:
Swapping objects using pointers
(10 answers)
Closed 7 years ago.
I want to make a swap function that can be generically used for any data type. I know that the following function works for ints:
void swap(void *a, void *b)
{
int temp;
temp = *(int*)a;
*(int*)a = *(int*)b;
*(int*)b = temp;
}
and this works for strings:
void swap(void *a, void *b)
{
void *temp;
temp = *(void**)a;
*(void**)a = *(void**)b;
*(void**)b = temp;
}
If you pass the size of the pointee along, too (like in qsort), then you can do it:
void swap(void * a, void * b, size_t len)
{
unsigned char * p = a, * q = b, tmp;
for (size_t i = 0; i != len; ++i)
{
tmp = p[i];
p[i] = q[i];
q[i] = tmp;
}
}
Usage:
struct Qux x, y;
swap(&x, &y, sizeof(Qux));
(You might want to add restrict qualifiers to the pointers, or otherwise a test for self-swapping.)
You should read the C FAQ list at least once. It is good to see what people have pondered over time.
Why can't I perform arithmetic on a void * pointer? is relevant to your question:
The compiler doesn't know the size of the pointed-to objects. (Remember that pointer arithmetic is always in terms of the pointed-to size; see also question 4.4.) Therefore, arithmetic on void *'s is disallowed (though some compilers allow it as an extension). Before performing arithmetic, convert the pointer either to char * or to the pointer type you're trying to manipulate (but see also questions 4.5 and 16.7).
Also relevant is Suppose I want to write a function that takes a generic pointer as an argument and I want to simulate passing it by reference. Can I give the formal parameter type void ** ...:
There is no generic pointer-to-pointer type in C. void * acts as a generic pointer only because conversions (if necessary) are applied automatically when other pointer types are assigned to and from void *'s; these conversions cannot be performed if an attempt is made to indirect upon a void ** value which points at a pointer type other than void *. When you make use of a void ** pointer value (for instance, when you use the * operator to access the void * value to which the void ** points), the compiler has no way of knowing whether that void * value was once converted from some other pointer type. It must assume that it is nothing more than a void *; it cannot perform any implicit conversions.
Here's another answer:
void swap(void *a, void *b, size_t width)
{
void *temp = malloc(width);
memcpy(temp, b, width);
memcpy(b, a, width);
memcpy(a, temp, width);
free(temp);
}

C cast void * to type_t

I have following code from an object-oriented programming C book:
{
struct Set { int count; };
struct Set * set = malloc(sizeof(struct Set));
void * p = set;
const size_t size = * (const size_t *) p;
}
I cant understand how and why last line works. size_t size is dereferenced value of pointer of type size_t. pointer of type type_t is cast from void* p.
What is happening when I cast void* to type_t*, I could not find any information in the book or online tutorials. Can someone explain it to me or refer me to a good tutorial?
So what happens here is the following: You have a pointer to a structure (p) and you cast it to a const size_t * pointer, and use the value resulted. Supposedly the value should be the same as the value of p->count however do not really count on this. According to Can I trust sizeof(size_t) <= sizeof(unsigned long int) is always true? int and size_t must not have the same size, so you well might end up with accessing memory which is not yours.
Here, the void * p is being casted to const size_t * type and used as the initializer for the const size_t size variable. The value in the address [of type const size_t ]held by p is being used.
When you cast void* p to size_t* p you are telling the compiler that p is pointing to a value of type size_t
In fact p is pointing to a a Set structure, which happens to contain a single int. The code is assuming that the type size_t is the same size as int, which the standard seems to suggest it will be
However size_t is unsigned, so if the value in the int is negative it will not be read correctly. Currently the data in the Set structure is uninitialised, so the result will be random

Given the address of a pointer, how do I get what it points to?

If I am given the address of a pointer, how do I get what the pointer points to?
You might mean:
/**
* #param pointer_to_pointer_to_int: the address of a pointer to an integer.
**/
void function_that_takes_pointer_to_pointer(int **pointer_to_pointer_to_int) {
int the_int = **pointer_to_pointer_to_int;
printf("The pointer points to %d\n", the_int);
}
Assuming it is a valid pointer, you can dereference it using the unary * operator:
int *ptr = ...;
int x;
x = *ptr;
The unary * operator.
int *ptr = malloc(sizeof(int));
*ptr = 45;
printf("address: %p, value: %d", ptr, *ptr);
The most common way to be given the address of a pointer is through a pointer to a pointer. If the value the pointer points to is an integer, the type of the address of the pointer is int **.
To get the pointer to the integer, you need to dereference the double pointer. Then you can dereference the integer pointer to get the integer value.
To dereference a pointer, use the * operator.
int **double_pointer = given;
int *int_pointer = *double_pointer;
int value = *int_pointer;
You can also chain the dereferences to do that on one line.
int **double_pointer = given;
int value = **double_pointer;
The unary * operator returns or sets the value at a memory location.
For example:
int val = 42;
int* ptr = &val;
assert(val == *ptr);
If you have the address of a pointer, you would write **pointerpointer.
Going off of RedX's comment, If you have a situation like
void foo(void *ptr)
{
...
}
where the value of ptr is a pointer to a pointer to int, for example, you could do something like
void foo(void *ptr)
{
int x = **((int **) ptr);
...
}
Basically, you cast ptr to int **, then double-dereference it.
If you don't know what the target type is ahead of time (e.g., the function is meant to handle pointers to multiple types), then you're going to have to figure out a way to encode that type information in a second argument and pass it to the function.
There are two possible answers to your question depending on whether the compiler has a clue about the data that's referred or not.
Declaring a pointer of type int *, char * or mytype * instructs the compiler that a later attempt to dereference it using the unary * operator must yield a result of int, char or mytype respectively.
In the other case you would normally store a pointer either in a void * (generic, untyped pointer) or in a uintptr_t (an unsigned int the same size of a pointer, but without pointer semantics). In such a case the compiler doesn't have a clue how to interpret the dereferencing operator, so you must explicitly cast such a pointer to another pointer type, and only then dereference it:
int x = 5;
void *p = &x; /* p now points to an int, but the compiler doesn't know it */
printf("%d\n", *((int *) p)); /* we know what we did and don't rely on the compiler */
printf("%d\n", *p); /* compile-time error, dereferencing has undefined semantics */
Note that in compiled, unmanaged languages like C there is no runtime information about what kind of data a pointer is pointing to, unlike languages like Java where you can use the instanceof operator to check what a reference is really pointing to at runtime.

Resources