0

I wanted to create a general print array function. This function would print array elements based on the data type.

#include "utilities.h"

//type : 0 ->int
//     : 1->char
void print_array(void *arr, int length, int type){
    int i = 0;

    for(i=0;i<length;i++){
        switch(type) {
            case 0:
                printf("Integer %d  %d\n", (int*)(arr+i));
                break;
            case 1:
               printf("%c \n", (char*)(arr+i));
               break;
            case 2:
                printf("%s \n", (char*)(arr+i));
                break;
            case 3:
                printf("%x \n", (int*)(arr+i));
                break;
            default:
                printf("Format not supported yet. %d \n",type);
                return;

        }
    }
}


void test_print_array(){
    int int_arr[3] = {0,1,2};
    print_array(int_arr,3,0);

}

int main(){
    test_print_array();
    return 0;
}

Output I am getting is

Integer -486474964

Integer -486474963

Integer -486474962

Instead of 0,1,2

I also tried using arr[i] instead of (int*)(arr+i) but I am getting compiler errors on that.

4
  • Post your compiler errors/warnings. Example: Review printf("%c \n", (char*)(arr+i));. %c expect a char` or int, not a pointer. Commented Apr 24, 2019 at 22:57
  • 1
    You're not dereferencing the pointers, and you're doing the pointer arithmetic on the uncast pointer and casting the result. Try eg. ((int *)arr)[i] instead of (int*)(arr+i) Commented Apr 24, 2019 at 22:58
  • You also might want to consider using an enum for the types... Commented Apr 24, 2019 at 23:00
  • You're using a compiler that allows pointer arithmetic on void*, like gcc. Those that do, consider the distance between "elements" to be 1. Commented Apr 24, 2019 at 23:18

2 Answers 2

3

You are using pointer arithmetic on void* type, whose size is unknown. You must cast the pointer before doing the arithmetc, but it is clearer to use array notation anyway.

#include <stdio.h>

void print_array(void *arr, int length, int type){
    int i = 0;

    for(i=0;i<length;i++){
        switch(type) {
            case 0:
                printf("int %d\n", ((int*)arr)[i]);
                break;
            case 1:
                printf("char %c\n", ((char*)arr)[i]);
                break;
            case 2:
                printf("string %s \n", ((char**)arr)[i]);
                break;
            case 3:
                printf("hex %X\n", ((unsigned*)arr)[i]);
                break;
            default:
                printf("Format not supported yet. %d \n",type);
                return;

        }
    }
}

void test_int_array(){
    int int_arr[3] = {0, 1, 2};
    print_array(int_arr, 3, 0);

}

void test_char_array(){
    char char_arr[3] = {'x', 'y', 'z'};
    print_array(char_arr, 3, 1);

}

void test_str_array(){
    char *str_arr[3] = {"one", "two", "three"};
    print_array(str_arr, 3, 2);

}

void test_uns_array(){
    unsigned uns_arr[3] = {26, 27, 28};
    print_array(uns_arr, 3, 3);

}

int main(){
    test_int_array();
    test_char_array();
    test_str_array();
    test_uns_array();
    return 0;
}

Program output:

int 0
int 1
int 2
char x
char y
char z
string one 
string two 
string three 
hex 1A
hex 1B
hex 1C

Sign up to request clarification or add additional context in comments.

Comments

0

A general print array function is prone to undefined behavior (UB) unless the data reference is aligned properly and of a valid value.

Having said that, try

//printf("Integer %d  %d\n", (int*)(arr+i));
//              vv-------- print a `%`
printf("Integer %%d  %d\n", ((int*)arr)[i]);
//                          ^---------^ form a `int *` and then use [i]

Adding i to a void* is UB. Cast the void * pointer first to the desired pointer type, then use the index [i].

3 Comments

utilities.c:11:47: error: operand of type 'void' where arithmetic or pointer type is required printf("Integer %d \n", (int*)arr[i]);
@user968000 Your comment does not include the () of the answer. Use ((int*)arr)[i] to insure proper evaluation. (int*)arr[i] is like (int*)(arr[i]) which is invalid.
works now : printf("Integer %d \n", ((int*)arr)[i]); thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.