zachyee
zachyee

Reputation: 346

Pointer Initialization to Iterate through Array

I have a function, where I have 2 void pointers (part of the specification), but I know they are char *. I want to iterate through the char arrays, so I tried to create some pointers to iterate through them. When I do the following, my program doesn't work:

int foo(void const * first, void const * second)
{
    char const * firstIt = (const char*) first;
    char const * secondIt = (const char*) second;
    ...
}

However, if I do:

int foo(void const * first, void const * second)
{
    char const * firstIt = *(const char**) first;
    char const * secondIt = *(const char**) second;
    ...
}

What is the difference between the two and why does the second one work? I don't know if I included enough detail, so if more information is needed I'd be happy to provide it.

Upvotes: 0

Views: 203

Answers (2)

Rob
Rob

Reputation: 1974

The first approach assumes the caller has passed a char * (const qualified in some way).

The second assumes the caller has passed a char ** (const qualified in some way).

If the second one works, that means your caller is passing a char **.

The reason the first wouldn't work is undefined behaviour. Having a pointer of one type, converting to another type, and dereferencing it as anything other than the original type gives undefined behaviour. A round trip via a void pointer doesn't change that.

That is why compilers complain about implicit conversions of one pointer type to another (except to and from void pointers).

Upvotes: 1

MightyMouse
MightyMouse

Reputation: 13798

If the second one works, this is because the void pointer that you indicate for the function can really be anything, and I am guessing that you are passing to the function the pointer of a pointer. For example, the following code works:

#include <stdio.h>
#include <stdlib.h>

int foo(void const * first, void const * second);
int goo(void const * first, void const * second);

int main () {
    char * a, * b;

    a = malloc (sizeof (char));
    b = malloc (sizeof (char));

    *a = 'z';
    *b = 'x';

    goo (&a, &b); /* critical line */

    free (a);
    free (b);

    return 0;
}

int foo(void const * first, void const * second) {
    char const * firstIt  = (const char*) first;
    char const * secondIt = (const char*) second;    
    printf ("%c %c", *firstIt, *secondIt);
    return 1;
}

int goo(void const * first, void const * second) {
    char const * firstIt = *(const char**) first;
    char const * secondIt = *(const char**) second;
    printf ("%c %c", *firstIt, *secondIt);
    return 2;
}

However, for the above program to work with the function foo you need to replace the critical line with a call of the form:

foo (a, b);

Does the difference make sense? Did it solve your problem?

Upvotes: 1

Related Questions