Как передать char ** указатель по значению? - PullRequest
2 голосов
/ 27 ноября 2011

Я хочу передать указатель на символ ** по значению. Учитывая следующий код:

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);
}

Я вызываю функцию f с помощью ptr. Я хочу сохранить первые значения ptr и использовать ptr1 в качестве его копии. Однако после операции подкачки и ptr, и ptr1 становятся одинаковыми. изменения в ptr. Как я могу передать его по значению?

Ответы [ 2 ]

2 голосов
/ 27 ноября 2011

Вы хотите глубокое копирование (в отличие от поверхностное копирование ) вашего символа **.Когда вы вызываете f (ptr), это как если бы вы писали

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

, и это дает понять, что ptr1 указывает на ту же область памяти, на которую указывает ptr.Так что не удивительно, что своп тоже влияет на ptr.

Как это исправить?Вы должны скопировать каждую строку одну за другой.Вы можете прочитать этот ответ на SO для аналогичной проблемы (это C ++, но суть та же).

ПРЕДЛОЖЕНИЕ Если возможно, я рекомендую

  1. избавиться от глобального указателя
  2. изменить init, чтобы он возвращал глобальный указатель вместо void, чтобы он выделял память и возвращал указатель на него
  3. возможно: создайтедругая функция, которая принимает на вход значения, с которыми вы инициализируете различные строки (две в вашем примере) символа **
  4. создаете функцию, которая освобождает всю выделенную память (я думаю, что, вероятно, выуже есть)

    Так что ваша функция f () будет инициировать () новый ptr1, будет принимать значения из ptr для инициализации значений ptr1 и будет вызывать своп для членов (еще лучше)Вы можете напрямую инициализировать, даже не меняя местами, просто вызовите с соответствующими аргументами функцию на шаге 3.

0 голосов
/ 27 ноября 2011
#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;
}
...