Search code examples
arrayscparameter-passingvoid-pointers

void pointer array parameter passing


i am trying to pass an int array as argument of a function who receives a void * array

The function is:

void foo(void *A[], unsigned int array_length)
{
    for (unsigned int i = 0; i < array_length; i++) {
        printf("%d ", (u32)(long)A[i]);
    }
}

Then i call like this:

int A[5] = {11, 12, 13, 14, 11};
foo((void *)A, 5);

but the printed array is: 11 13 11 -2015754187 -274447056 and i dont understand why this numbers are printed.


Solution

  • Actually i need to be able to receive an array of any type because my intention is not to print them but to enqueue them in a queue.

    What your foo function lacking is determining the type of data that should be passed as an argument, without it we cannot extract values properly from void*

    Below is one of the ways to achieve what you are asking. Here I am passing the type of data and manipulating.

    NOTE: This is not a generic function, it is just made to to handle some known types. you can add more types (pointers and structs etc.) and experiment.

    I am printing the data just to be sure we are extracting what we passed, but you can use them as per your need.

    
    #include <stdio.h>
    
    typedef enum  { CHAR = 0, INT, FLOAT, STRING} DataType;
    
    const char* getType(DataType t)
    {
        if(t == CHAR)
            return "CHAR";
        else if(t == INT)
            return "INT";
        else if(t == FLOAT)
            return "FLOAT";
        else
            return "STRING";
    }
    
    void foo(void *A, unsigned int array_length, DataType type )
    {
        printf("type is %s and len = %d\n", getType(type), array_length);
        
        switch(type)
        {
            case CHAR:
            {
                char *list = (char *) A;
                for (unsigned int i = 0; i < array_length; i++) {
                    printf("%c ", list[i]);
                }
            }
            break;
            
            case INT:
             {
                int *list = (int *) A;
                for (unsigned int i = 0; i < array_length; i++) {
                    printf("%d ", list[i]);
                }
             }
            break;
            
            case FLOAT:
             {
                float *list = (float *) A;
                for (unsigned int i = 0; i < array_length; i++) {
                    printf("%.2f ", list[i]);
                }
             }
            break;
            
            case STRING:
             {
                char**list = (char**) A;
                for (unsigned int i = 0; i < array_length; i++) {
                    printf("%s ", list[i]);
                }
             }
            break;
            
            default:
                printf("Invalid type");
                break;
        }
        putchar('\n');
    }
    
    int main()
    {
        int arr_int[] = {11, 12, 13, 14, 11};
        //char arr_char[] = {"abcde"}; better way we have '\0' at the end
        char arr_char[] = {'a','b','c','d','e'};
        float arr_float[] = {11.20, 12.25, 13.70, 14.80, 11.15};
        char* arr_strings[] = {"abc","def","ghi","jkl","mno"};
        
        foo(arr_int, sizeof(arr_int) / sizeof(arr_int[0]), INT);
        foo(arr_char, sizeof(arr_char) / sizeof(arr_char[0]), CHAR);
        foo(arr_float, sizeof(arr_float) / sizeof(arr_float[0]), FLOAT);
        foo(arr_strings, sizeof(arr_strings) / sizeof(arr_strings[0]), STRING);
        
        return 0;
    }