Question

i have a function like

void printMe (void *i)
{
    printf("%d", i);
}

where i want to pass a void pointer and print it to screen. The above example is fine if the i is integer, float or double but crashes if i is a char. There is no overloading in C like i usually use in C++. So the question is this, can we create a function in C that will print the element that is it's parameter, and if yes how is this possible because it totally eludes me at this moment.

Was it helpful?

Solution

Q1: So the question is this, can we create a function in C that will print the element that is it's parameter

A: Not in the way you want. You will have to pass information to the function, telling it the type of data you're passing.

Q2: and if yes how is this possible because it totally eludes me at this moment.

A: It's eluding you because it can't be done. There is no metadata associated with a void* that the compiler or runtime can use to figure out they type it's pointing to. You need to either

  1. pass a structure that contains a
    pointer and information about what
    the pointer points to (e.g. an enum).
  2. pass an extra parameter with information about what the pointer points to

As the code stands the only thing you can print here is the address that i points to.

A void pointer points to raw data, printf assumes you know what data type you're printing, it has no intelligence and cannot "figure it out" for you.

It's that simple.

What you can do is pass type information to the function, but then you end up with something very like printf it's self, where you pass a formatting string containing type information about the data in the following arguements.

Hope this helps.

Also . . . "There is no overloading in C like i usually use in C++"

Even in c++ the overloading happens at compile time, and here there's no way for the compiler to know what data will be passed to that function, so even though you're used to overloading, it would never work like this (e.g. try this same thing using printf, but compile it with a C++ compiler, you'll get exactly the same results). Actually try

cout << i;

in the function above, and it will give you the address i points to, not the "value" of i. You'd need to cast i and derference it before you could get it's value

cout << *(int*)i;

So, to get the above working in C++ you'd need to have lots of overloaded functions (or a template function, which is really the same thing, except the compiler rolls the functions for you) e.g. overloaded functions

printMe(int i){...}
printMe(double d){...}
printMe(char c){...}
printMe(char* string){...}

In c you just need to give those functions specific names

printInt(int i){...}
printDouble(double d){...}
printChar(char c){...}
printString(char* string){...}

OTHER TIPS

For a start, you're printing the pointer, not what it points to. To print the actual contents, you need to pass *i to printf, not i.

If you really want to do this, one solution is:

void printMe (void *p, int typ) {
    switch(typ) {
        case TYP_INT: printf("%d", *((int*)p)); break;
        case TYP_CHR: printf("%c", *((char*)p)); break;
        /* and so on ... */
    }
}

So the question is this, can we create a function in C that will print the element that is it's parameter

Yes, we can. Such a function is already part of the standard library - it's called printf ;)

As there is no compile-time function overloading in C, you somehow have to supply the type of the arguments at runtime. The printf format string can be used to do this, so there's really no reason to build your own wrapper function when there's already a working solution.

If you are trying to print out the pointer value, the correct usage is printf("%p", i);. The 'd' specifier is for integers, and the 'p' is for pointers. It's your responsibility to get these correct, and bad things can happen if you mix them up.

I don't know why this would fail for a char * and not an int *, and it is possible you've got other problems causing this. If it still fails with %p, something else got messed up. See if you can install some sort of memory monitor software to check for dangling pointers or double free()s, because at that point the smart money's that you've corrupted memory somewhere.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top