简体   繁体   中英

how to use void pointer as function return type In C

So I am planing to Write a function to return a random array element. The function accept two parameters—an array of void pointers and the array length. It should return a void pointer. The idea is to take the given array, which comes in the form of an array of void pointer, the function will return an random element of the the array. The question I have is, what do I need to do to return a pointer, what do I need to do to the "result" so I can return it like that? After wards what do I need to do to access it again? Thanks

Here is what I have done, but I'm getting the:

 "25: error: invalid use of void expression"

with warnings like:

" warning: pointer of type ‘void *’ used in arithmetic"

My code:

#include<stdlib.h>
#include<stdio.h>
#include<time.h>
void *randomNum(void * array, int length)
{
    void * result;  
    result=array[rand()%(length-1)];
    return result;
}    
int main()
{
int i;
srand(13);
int array[9]={1,5,6,85,132,65463,1354,5863,134};

for (i=0;i<9; i++)
{
    printf("%d\n",*randomNum(array,9));
}



return 0;
}

You can write a perfectly fine generic function this way, but:

    result = array[rand()%(length-1)];

This is dereferencing the void pointer array while also attempting to store it into a pointer result . What you want to store is the address at that offset:

    result = array + rand()%(length-1);

However, you can't perform arithmetic like this on void pointers either, as the size of the underlying type is not known (some compilers allow sizeof(void)==1 as an extension). With a non-void array, the number of bytes a given element consumes, and thus the number of bytes to increment by when doing arithmetic on the address, is encoded in the type. In a generic function operating on void pointers like this one you'll need to explicitly pass the size of the type.

void *randomNum(void * array, size_t size, size_t length)

Now perform the calculation by casting array to a char pointer, which forces arithmetic on array to occur in increments of 1 byte times the provided size parameter:

    result = (char*)array + (rand()%(length-1)) * size;
                   ^                            ^

You can then call randomNum with randomNum(array, sizeof(*array), 9)

However, you still need to cast the return value of the function before dereferencing it.

    printf("%d\n", *(int*)randomNum(array,sizeof(*array),9));

There are a number of problems with the approach:

1) Since the argument array is of type void * , your plan of indexing it based on length will not work—for indexing to work, the length of each element in your array needs to be known as well. You seem to be trying to make a generic function that would work for any type of array, but honestly it's simpler to make a separate function for different types of arrays.

(To see why this is problematic, remember that array[index] is equivalent to *(array + index) ; by indexing the void * you are applying pointer arithmetic to and then dereferencing the void pointer . Meditate on this.)

2) You are dereferencing a void pointer when you do *randomNum(array, 9) . This cannot be done; you need to cast the pointer to an appropriate type first, ie, *((int *)randomNum(array, 9)) , but as I said above, the whole approach with randomNum dealing in void pointers is problematic, so just change the whole thing to:

int *randomNumInt(int *array, size_t length)

Your problem (well, the one causing the error) is: *randomNum(array,9)

Remember that the return type of randomNum is void * , which you dereference. The expression is therefore void. That does not make much sense to the compiler, and it issues an error.

Now, I am not quite sure why you declared randomNum to return void* , you might instead just have declared it int . You effectively convert an array value to a void * , which would point somewhere to the beginning og memory - an invalid location. If you were to cast the pointer to int* , your program would segfault.

You can't dereference a void pointer like *randomNum(array,9) in your program. You should have to cast it before doing anything with void pointer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM