thetux4
thetux4

Reputation: 1633

How to pass a char ** pointer by value?

I want to pass a char ** pointer by value. Given the following code:

char **ptr; 

void init(){
    int i;
    ptr = (char**)malloc(2 * sizeof(char*));
    for(i=0;i<2;i++){
         ptr[i]=(char*)malloc(3 * sizeof(char));
         ptr[i] = ..//assign different strings of length 2
    }
}

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

void f(char **ptr1){
    //swap the first and second element
    swap(&ptr1[0],&ptr1[1]);
}

int main{
    init();
    f(ptr);
}

I call the function f with ptr. I want to keep ptr's first values and want to use ptr1 as a copy of it. However, after the swap operation both ptr and ptr1 becomes same. ptr changes. How can I pass it by value?

Upvotes: 2

Views: 584

Answers (2)

wildplasser
wildplasser

Reputation: 44220

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

char ** init()
{
    char **ret;

    ret = malloc(2 * sizeof *ret);
    ret[0] = "world!" ;
    ret[1] = "Hello " ;
    return ret;
}

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

void f(char **ptr1)
{
    //swap the first and second element
    swap(&ptr1[0],&ptr1[1]);
}

int main(void) /* here! */
{
    char **ptr;
    ptr = init();
    f(ptr);
    printf("%s%s\n", ptr[0], ptr[1] );
    return 0;
}

Upvotes: 0

Francesco
Francesco

Reputation: 3250

You want to deep copy (as opposed to shallow copy) your char**. When you call f(ptr), it's like if you were writing

ptr1 = ptr; // by the way, why ptr is global?

and this makes it plain that ptr1 it is pointing to the same area of memory pointed to by ptr. So it's not strange that the swap is affecting ptr, too.

How to fix it? You have to copy each string one by one. You can read this answer on SO for a similar issue (it's C++ but the point is the same).

SUGGESTION If possible, I recommend to

  1. get rid of the global pointer

  2. change init to return the global pointer instead of void, so that it allocates memory and returns a pointer to it

  3. possibly: create a different function which takes in input the values with which you initialize the various strings (Two in your example) of the char**

  4. create a function which frees all the memory allocated (I guess that probably you already have it)

    So that your f() function will init() a new ptr1, will take the values from ptr to initialize the values of the ptr1, and will call the swap on the members (better yet, you can directly initialize without even swapping, just call with the appropriate arguments the function at step 3.

Upvotes: 2

Related Questions