Home > Enterprise >  converting a string to a void pointer
converting a string to a void pointer

Time:06-29

I'm trying to figure out how to "transform" strings (char*) to void* and viceversa. When I execute this my output is just the first printf and ignores the second one, it doesn't even write "after = "

PS This little program is just to understand, I know i could actually use swap(&s[0],&s[1]). I need to know how to properly cast a void pointer into an array of strings. I'm working on a uni project where I need to create my own quick_sort algorythm and I need the swap function inside of it to work with void pointers.

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

static void swap(char** x,char** y);

static void swap(char** x,char** y){
    char* temp=*x;
    *x=*y;
    *y=temp;
}

int main()
{
    char* s[2];
    s[0]="weee";
    s[1]="yooo";
    void* array=s;
    printf("before %s %s\n",s[0],s[1]);
    swap((&array)[0],(&array)[1]);
    printf("after = %s %s",(char*)array,(char*)array);
    return 0;
}

I think I'm missing something big Thanks in advance :D

CodePudding user response:

In this declaration the array s used as an initializer is implicitly converted to a pointer to its first element of the type char **.

void* array = s;

In the call of the function swap

swap((&array)[0],(&array)[1]);

the first argument can be the pointer array itself that will be implicitly casted to the pointer type of the corresponding parameter

swap( array, (&array)[1]);

But you need to correctly pass the second argument. To do this you need to cast the pointer array explicitly like

swap( array, ( char ** )array   1 );

In the call of printf you need also correctly to supply argument expressions.

Here is your updated program

#include <stdio.h>

static void swap(char** x,char** y);

static void swap(char** x,char** y){
    char* temp=*x;
    *x=*y;
    *y=temp;
}

int main()
{
    char* s[2];
    s[0]="weee";
    s[1]="yooo";
    void* array=s;
    printf("before %s %s\n",s[0],s[1]);
    swap( array, ( char ** )array   1 );
    printf("after = %s %s", *(char**)array, ( (char**)array )[1]);
    
    return 0;
}

The program output is

before weee yooo
after = yooo weee

CodePudding user response:

void *array = s; declares array to be a void *. Then &array is the address of that void *, so &array[1] would access a void * after it. But there is no void * after it, since void *array defines a single void *.

array could be properly defined to alias s with char **array = s;, after which swap(&array[0], &array[1]); would work as desired.

If you define array as void **array = (void **) s;, then swap(&array[0], &array[1]); will produce diagnostic messages because the types are wrong. You could use swap((char **) &array[0], (char **) &array[1]);.

Then, if you print the strings with printf("after = %s %s", array[0], array[1]);, this will work, although it is not entirely proper code. Using array[0] as an argument passes a void * where printf is expecting a char * for the %s. However, the C standard guarantees that void * and char * have the same representation (encode their values using bytes in memory in the same way), and it further says (in a non-normative note) that this is intended to imply interchangeability as arguments to functions.

CodePudding user response:

The void* doesn't seem to fulfil any particular purpose here, just swap the pointers: swap(&s[0],&s[1]);.

You could also do this:

char** ptr = &s[0];
printf("before %s %s\n",ptr[0],ptr[1]);
swap(&ptr[0],&ptr[1]);
printf("after = %s %s",ptr[0],ptr[1]);

If you for reasons unknown insist on using void* then note that as your code stands, it points at the first char* in your array of char*. However, it isn't possible to perform pointer arithmetic on void* since that would entail knowing how large a "void" is. The void* doesn't know that it points at an array of pointers. Therefore array[i] is nonsense.

Also, the void* are set to point at char* so you simply cannot pass it to a function expecting a char**. You'd have to rewrite the whole program in a needlessly obfuscated way, so just abandon that idea.

  • Related