I'm trying to write a function that takes a void pointer to an int and then doubles the int, and puts it back into the memory location:
void doubleNumber(void *number){
number = &((*((int*)(number))) * 2);
}
So first I cast it into an int * from a void *, then I deference the int * to get the value, then I multiply by 2 and then I get the address of that to put it back into the pointer.
Can anyone give me tips on why my logic is not working?
Thanks
I'd write it like this:
void doubleNumber(void *number){
*(int*)number *= 2;
}
First of all cast number to be of type int*. Then dereference the pointer. Then double it.
The problem with your code is that you are assigning the pointer rather than the pointee.
Step 1:
void doubleNumber(int *value) {
*value = 2 * (*value);
}
Step 2:
void doubleNumber(void *value) {
int * ivalue = (int *)value;
*ivalue = 2 * (*ivalue);
}
Firstly, arguments to functions in C are passed by value, so modification of number will have no effect.
Secondly, even if it did, you should allocate some memory for the value first. Only then can you return a pointer to this place in memory.
A value (such as 2) has no address.
Instead, simply write:
* (*int)number = *(int*) number) * 2;
or, shorter:
* (*int)number *= 2;
Related
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.
My question is in the title and is more of a syntax related question. Does anyone know what the * is doing in the function below? See here:
int* reat(int *n)
{
int i, *array;
do
{
printf("n="); scanf("%d", n);
} while (*n < 1);
array = (int *)malloc(*n * sizeof(int));
for (i = 0; i < *n; i++)
{
printf("%d. broj: ", i + 1);
scanf("%d", array + i);
}
return array;
}
The syntax
int i, *array;
declares i to be a variable of type int and array to be a variable of type int*. This sort of declaration isn't particularly common, but is legal C code.
Hope this helps!
The * in int* reat(int *n) indicates in the return that this function is returning a pointer to an integer value rather than the integer value itself. The * indicates in the argument list that this function also wants a pointer to an integer value rather than a "raw" integer value for its argument.
For example,
int x = reat(n); // assume n is a pointer to an int
probably won't compile on most systems. If it does, you'll be storing a memory address in x rather than the integer value you were expecting. Instead write
int *x = reat(n)
to store in x the pointer (to some integer value) returned by reat(). Consider this function:
int addone(int x) {
return 1 + x;
}
This function takes an integer value for its argument. To access the value of the integer pointed to by the return from reat() and use it in addone(), we'll need to call it like so:
int *x = reat(n)
addone(*x)
Thereby dereferencing x with the * operator to access the integer value it points to. addone(x) won't compile because x, without dereferencing, is a memory address and not an integer.
Understanding when the * is being used to define a pointer and when its being used to dereference one will become second nature over time. Trust that any time it shows up in a function definition, whether as an argument or a return, it indicates a pointer is being used.
can someone help with this piece of code? I leaved out check of allocations to keep it brief.
typedef struct {
int x;
int y;
} MYSTRUCT;
void init(MYSTRUCT **p_point);
void plusOne(MYSTRUCT **p_point, int *p_size);
int main()
{
MYSTRUCT *point;
int size = 1;
init(&point);
plusOne(&point, &size);
plusOne(&point, &size);
point[1]->x = 47; // this was the problem
point[1].x = 47; // this is solution
return 0;
}
void init(MYSTRUCT **p_point)
{
*p_point = (MYSTRUCT *) malloc( sizeof(MYSTRUCT) );
}
void plusOne(MYSTRUCT **p_point, int *p_size)
{
(*p_size)++;
*p_point = realloc(*p_point, *p_size * sizeof(MYSTRUCT) ); // also calling to the function is fixed
}
I don't understand why index notation doesn't work after calling to functions.
This is because you are not multiplying the p_size by sizeof(MYSTRUCT) in the call of realloc, and not assigning the results back to p_point:
*p_point = realloc(*p_point, *p_size * sizeof(MYSTRUCT));
Notes:
You do not need to cast the result of malloc or realloc in C.
For consistency, consider passing &size to init, and set it to 1 there.
You have some type confusion going on... Here:
MYSTRUCT *point;
you declare point to be a pointer to a MYSTRUCT structure (or an array of them).
The syntax point[i] is equivalent to *(point + i) - in other words, it already dereferences the pointer after the addition of the appropriate offset, yielding a MYSTRUCT object, not a pointer to one.
The syntax p->x is equivalent to (*p).x. In other words, it also expects p to be a pointer, which it dereferences, and then yields the requested field from the structure.
However, since point[i] is no longer a pointer to a MYSTRUCT, using -> on it is wrong. What you are looking for is point[i].x. You could alternatively use (point + i) -> x, but that's considerably less readable...
Is it possible to dereference a void pointer without type-casting in the C programming language?
Also, is there any way of generalizing a function which can receive a pointer and store it in a void pointer and by using that void pointer, can we make a generalized function?
for e.g.:
void abc(void *a, int b)
{
if(b==1)
printf("%d",*(int*)a); // If integer pointer is received
else if(b==2)
printf("%c",*(char*)a); // If character pointer is received
else if(b==3)
printf("%f",*(float*)a); // If float pointer is received
}
I want to make this function generic without using if-else statements - is this possible?
Also if there are good internet articles which explain the concept of a void pointer, then it would be beneficial if you could provide the URLs.
Also, is pointer arithmetic with void pointers possible?
Is it possible to dereference the void pointer without type-casting in C programming language...
No, void indicates the absence of type, it is not something you can dereference or assign to.
is there is any way of generalizing a function which can receive pointer and store it in void pointer and by using that void pointer we can make a generalized function..
You cannot just dereference it in a portable way, as it may not be properly aligned. It may be an issue on some architectures like ARM, where pointer to a data type must be aligned at boundary of the size of data type (e.g. pointer to 32-bit integer must be aligned at 4-byte boundary to be dereferenced).
For example, reading uint16_t from void*:
/* may receive wrong value if ptr is not 2-byte aligned */
uint16_t value = *(uint16_t*)ptr;
/* portable way of reading a little-endian value */
uint16_t value = *(uint8_t*)ptr
| ((*((uint8_t*)ptr+1))<<8);
Also, is pointer arithmetic with void pointers possible...
Pointer arithmetic is not possible on pointers of void due to lack of concrete value underneath the pointer and hence the size.
void* p = ...
void *p2 = p + 1; /* what exactly is the size of void?? */
In C, a void * can be converted to a pointer to an object of a different type without an explicit cast:
void abc(void *a, int b)
{
int *test = a;
/* ... */
This doesn't help with writing your function in a more generic way, though.
You can't dereference a void * with converting it to a different pointer type as dereferencing a pointer is obtaining the value of the pointed-to object. A naked void is not a valid type so derefencing a void * is not possible.
Pointer arithmetic is about changing pointer values by multiples of the sizeof the pointed-to objects. Again, because void is not a true type, sizeof(void) has no meaning so pointer arithmetic is not valid on void *. (Some implementations allow it, using the equivalent pointer arithmetic for char *.)
You should be aware that in C, unlike Java or C#, there is absolutely no possibility to successfully "guess" the type of object a void* pointer points at. Something similar to getClass() simply doesn't exist, since this information is nowhere to be found. For that reason, the kind of "generic" you are looking for always comes with explicit metainformation, like the int b in your example or the format string in the printf family of functions.
A void pointer is known as generic pointer, which can refer to variables of any data type.
So far my understating on void pointer is as follows.
When a pointer variable is declared using keyword void – it becomes a general purpose pointer variable. Address of any variable of any data type (char, int, float etc.)can be assigned to a void pointer variable.
main()
{
int *p;
void *vp;
vp=p;
}
Since other data type pointer can be assigned to void pointer, so I used it in absolut_value(code shown below) function. To make a general function.
I tried to write a simple C code which takes integer or float as a an argument and tries to make it +ve, if negative. I wrote the following code,
#include<stdio.h>
void absolute_value ( void *j) // works if used float, obviously it must work but thats not my interest here.
{
if ( *j < 0 )
*j = *j * (-1);
}
int main()
{
int i = 40;
float f = -40;
printf("print intiger i = %d \n",i);
printf("print float f = %f \n",f);
absolute_value(&i);
absolute_value(&f);
printf("print intiger i = %d \n",i);
printf("print float f = %f \n",f);
return 0;
}
But I was getting error, so I came to know my understanding with void pointer is not correct :(. So now I will move towards to collect points why is that so.
The things that i need to understand more on void pointers is that.
We need to typecast the void pointer variable to dereference it. This is because a void pointer has no data type associated with it. There is no way the compiler can know (or guess?) what type of data is pointed to by the void pointer. So to take the data pointed to by a void pointer we typecast it with the correct type of the data holded inside the void pointers location.
void main()
{
int a=10;
float b=35.75;
void *ptr; // Declaring a void pointer
ptr=&a; // Assigning address of integer to void pointer.
printf("The value of integer variable is= %d",*( (int*) ptr) );// (int*)ptr - is used for type casting. Where as *((int*)ptr) dereferences the typecasted void pointer variable.
ptr=&b; // Assigning address of float to void pointer.
printf("The value of float variable is= %f",*( (float*) ptr) );
}
A void pointer can be really useful if the programmer is not sure about the data type of data inputted by the end user. In such a case the programmer can use a void pointer to point to the location of the unknown data type. The program can be set in such a way to ask the user to inform the type of data and type casting can be performed according to the information inputted by the user. A code snippet is given below.
void funct(void *a, int z)
{
if(z==1)
printf("%d",*(int*)a); // If user inputs 1, then he means the data is an integer and type casting is done accordingly.
else if(z==2)
printf("%c",*(char*)a); // Typecasting for character pointer.
else if(z==3)
printf("%f",*(float*)a); // Typecasting for float pointer
}
Another important point you should keep in mind about void pointers is that – pointer arithmetic can not be performed in a void pointer.
void *ptr;
int a;
ptr=&a;
ptr++; // This statement is invalid and will result in an error because 'ptr' is a void pointer variable.
So now I understood what was my mistake. I am correcting the same.
References :
http://www.antoarts.com/void-pointers-in-c/
http://www.circuitstoday.com/void-pointers-in-c.
The New code is as shown below.
#include<stdio.h>
#define INT 1
#define FLOAT 2
void absolute_value ( void *j, int *n)
{
if ( *n == INT) {
if ( *((int*)j) < 0 )
*((int*)j) = *((int*)j) * (-1);
}
if ( *n == FLOAT ) {
if ( *((float*)j) < 0 )
*((float*)j) = *((float*)j) * (-1);
}
}
int main()
{
int i = 0,n=0;
float f = 0;
printf("Press 1 to enter integer or 2 got float then enter the value to get absolute value\n");
scanf("%d",&n);
printf("\n");
if( n == 1) {
scanf("%d",&i);
printf("value entered before absolute function exec = %d \n",i);
absolute_value(&i,&n);
printf("value entered after absolute function exec = %d \n",i);
}
if( n == 2) {
scanf("%f",&f);
printf("value entered before absolute function exec = %f \n",f);
absolute_value(&f,&n);
printf("value entered after absolute function exec = %f \n",f);
}
else
printf("unknown entry try again\n");
return 0;
}
Thank you,
No, it is not possible. What type should the dereferenced value have?
void abc(void *a, int b) {
char *format[] = {"%d", "%c", "%f"};
printf(format[b-1], a);
}
Here is a brief pointer on void pointers: https://www.learncpp.com/cpp-tutorial/613-void-pointers/
6.13 — Void pointers
Because the void pointer does not know what type of object it is pointing to, it cannot be dereferenced directly! Rather, the void pointer must first be explicitly cast to another pointer type before it is dereferenced.
If a void pointer doesn't know what it's pointing to, how do we know what to cast it to? Ultimately, that is up to you to keep track of.
Void pointer miscellany
It is not possible to do pointer arithmetic on a void pointer. This is because pointer arithmetic requires the pointer to know what size object it is pointing to, so it can increment or decrement the pointer appropriately.
Assuming the machine's memory is byte-addressable and does not require aligned accesses, the most generic and atomic (closest to the machine level representation) way of interpreting a void* is as a pointer-to-a-byte, uint8_t*. Casting a void* to a uint8_t* would allow you to, for example, print out the first 1/2/4/8/however-many-you-desire bytes starting at that address, but you can't do much else.
uint8_t* byte_p = (uint8_t*)p;
for (uint8_t* i = byte_p; i < byte_p + 8; i++) {
printf("%x ",*i);
}
I want to make this function generic,
without using ifs; is it possible?
The only simple way I see is to use overloading .. which is not available in C programming langage AFAIK.
Did you consider the C++ programming langage for your programm ? Or is there any constraint that forbids its use?
Void pointers are pointers that has no data type associated with it.A void pointer can hold address of any type and can be typcasted to any type. But, void pointer cannot be directly be dereferenced.
int x = 1;
void *p1;
p1 = &x;
cout << *p1 << endl; // this will give error
cout << (int *)(*p) << endl; // this is valid
You can easily print a void printer
int p=15;
void *q;
q=&p;
printf("%d",*((int*)q));
Because C is statically-typed, strongly-typed language, you must decide type of variable before compile. When you try to emulate generics in C, you'll end up attempt to rewrite C++ again, so it would be better to use C++ instead.
void pointer is a generic pointer.. Address of any datatype of any variable can be assigned to a void pointer.
int a = 10;
float b = 3.14;
void *ptr;
ptr = &a;
printf( "data is %d " , *((int *)ptr));
//(int *)ptr used for typecasting dereferencing as int
ptr = &b;
printf( "data is %f " , *((float *)ptr));
//(float *)ptr used for typecasting dereferencing as float
You cannot dereference a pointer without specifying its type because different data types will have different sizes in memory i.e. an int being 4 bytes, a char being 1 byte.
Fundamentally, in C, "types" are a way to interpret bytes in memory. For example, what the following code
struct Point {
int x;
int y;
};
int main() {
struct Point p;
p.x = 0;
p.y = 0;
}
Says "When I run main, I want to allocate 4 (size of integer) + 4 (size of integer) = 8 (total bytes) of memory. When I write '.x' as a lvalue on a value with the type label Point at compile time, retrieve data from the pointer's memory location plus four bytes. Give the return value the compile-time label "int.""
Inside the computer at runtime, your "Point" structure looks like this:
00000000 00000000 00000000 00000000 00000000 00000000 00000000
And here's what your void* data type might look like: (assuming a 32-bit computer)
10001010 11111001 00010010 11000101
This won't work, yet void * can help a lot in defining generic pointer to functions and passing it as an argument to another function (similar to callback in Java) or define it a structure similar to oop.
I am trying to use a double void pointer but I am a little bit confused about the usage.
I have a struct that contains a void ** array.
struct Thing{
void ** array;
};
struct Thing * c = malloc (sizeof(struct Thing));
c->array = malloc( 10 * sizeof(void *) );
So If I want to assign a different object to each pointer and try to retrieve the value
// Option 1
*(c->array + index) = (void *) some_object_ptr;
// Option 2
c->array[index] = (void *) some_object_ptr;
then, I have another function that gives (void *) item that points to each cell, not the some_object_ptr.
If I want to retrieve the value which pointed to by some_object_ptr,
should I do
function return type is 'void *' and takes argument 'void *'
// Option 3
return (void**) item
// Option 4
return *((void**)item)?
the weird thing is that when I used array the array subscript method I couldn't use option 4, only option 3; and when I used *(c->array + index) I could only use opt.4. and not opt.3. ..
Can anyone please tell me about this? If I am making any invalid assumptions, then could you please correct me?
A void ** is just a pointer to a pointer to memory with an unspecified type. You can only dereference it once (since you can't dereference a void *). However, apart from that, it is basically like any other pointer type. If it helps you, think of it the same way as you would with int *.
So, in your specific situation, we have:
void** array;
int arrayLen = 10;
array = (void**)malloc(arrayLen * sizeof(void*));
some_type_t* some_object_ptr;
// The following two assignment are equivalent since in C,
// array[index] <=> *(array + index)
array[index] = (void*)some_object_ptr;
*(array + index) = (void*)some_object_ptr;
Then array is a pointer to the whole array, while *array is a pointer to the first element, since it is equivalent to array[0].
One quick hint about pointers: if you are casting it, you are probably doing something wrong.
As for your question. I am not sure what item is in your problem. In your first part you've already discovered how to acces a member in your array. You could simply use it:
void *get_item(Thing *c, int index)
{
return *(c->array + index); // or return c->array[index];
}
If you need the address of the pointer at index:
void **get_item_cell(Thing *c, int index)
{
return c->array + index; // or return &c->array[index];
}
In the second part, you don't dereference the pointer (for + option), or take the address of array result, since it automatically dereferences it.
EDIT:
I think I now know what you want. You have a function similar to my second one above, but it is:
void *get_item_cell(Thing *c, int index)
{
return (void *)(c->array + index);
}
You want to dereference the value returned from this function, and access the object. In that case, you can only use Option 4 safely. Since you don't have the index, you cannot move to any other cell (you don't know if you are at the end of the array, or at the beginning - so no additions or subtractions). You can only fix the mistake of the above function: cast to void **, and then dereference it: *(void **)item. This will give you a void *. If you want to access the object pointed from this cell, you need to cast that to the correct type as well: some_object_ptr *obj = *(void**)item.
The fact you are working with void* and void** doesn't matter, pointer arithmetic still works fine, so both options you wrote are correct.
Here's an example:
struct Thing
{
void ** array;
};
struct Object
{
int i;
char c;
};
int main ()
{
struct Thing * c = malloc (sizeof(struct Thing));
c->array = malloc(10 * sizeof(void*));
struct Object * o = malloc (sizeof(struct Object));
o->i = 2; o->c = 'a';
*(c->array + 2) = o;
printf("Object: i = %d, c = %c\n", ((Object*)c->array[2])->i, ((Object*)c->array[2])->c);
free(o);
free(c->array);
free(c);
return 0;
}
Since it's void* you can put there pointer to whatever, just don't forget it to cast to original type before using it ;)
Almighty push!
any_type x ;
void * v = * ( void * * ) & x ;
almighty pull!
void * v ;
any_type x = * ( any_type * ) & v ;
beware of losing/gaining digits