Как назначить один указатель в двойной указатель - PullRequest
0 голосов
/ 28 мая 2018

Итак, я видел этот пример:

int main()
{
  char *ls[] = {"ls", NULL};
  char *grep[] = {"grep", "pipe", NULL};
  char *wc[] = {"wc", NULL};
  char **cmd[] = {ls, grep, wc, NULL};

  loop_pipe(cmd);
  return (0);
}

И loop_pipe () - это функция для управления аргументами для нескольких каналов.Но переменные в этом коде, которые вставляются в cmd, уже определены.В моем личном коде я пытаюсь сделать обратное, создать переменную, вставить аргументы в переменную и затем добавить ее в cmd.Но чего не происходит, так это необходимости «добавления».Например, код выглядит следующим образом:

*(cmd[pipe_count]) = arg;

Я предполагаю, что что-то не так (потому что он не работает), но не использует индекс для установки места вставки, достаточного для выделения указателямассив внутри моего двойного указателя?Если нет, может кто-нибудь помочь мне понять, как назначить так?

Edit1:

Мой упрощенный код выглядит так:

char* arg[100];
char** cmd[100] = {};
int pipe_count = 0;
int index = 0;
arg[pipe_count] = (char *) malloc(sizeof(char) * 100);
    for (int k = 0; params_vector[k][0] != '\0'; k++) {             // percorrer todos os parametros. exemplo: ls | less | sort
        if (strcmp(params_vector[k], "|") != 0) {
            arg[index] = params_vector[k];
            index++;
        } else {
            arg[index] = '\0';
            *(cmd) = arg;
            pipe_count++;
            arg[pipe_count] = (char *) malloc(sizeof(char) * TAM);
            index = 0;
        }
    }

1 Ответ

0 голосов
/ 29 мая 2018

Вы можете думать о char **cmd[] как о массиве, который содержит char ** элементов.Таким образом, вы можете присвоить ему char ** элементов.

cmd[i] = arg;

Это так просто.Он не сильно отличается от массива целых чисел.

// "foo" is a `const char[]`. So an array of them is a `const char *[]`
const char *ls[] = {"ls", NULL};
const char *grep[] = {"grep", "pipe", NULL};
const char *wc[] = {"wc", NULL};

// To store an array of `const char *[]` we need a `const char **[]`.
const char **cmd[10] = {NULL};

cmd[0] = ls;
cmd[1] = grep;
cmd[2] = wc;

Подробнее ...

Для простоты, остальная часть этого примера будет обрабатывать char *[] и char ** одинаково,Есть некоторые тонкие различия, но для наших целей они не имеют значения.Мы будем рассматривать ls, grep и wc как char ** указатели, а cmd как char ***.

char **cmd[10] выделяет место для 10 char ** указателей на стек .char ** имеют тот же размер, что и любые другие указатели.Мы примем 64-битные целые или 8 байтов.10 из них означает, что он выделяет 80 байтов.cmd сам по себе является char *** указателем.Это имеет значение только для компилятора в целях проверки типа.В конечном итоге все, что содержит cmd, представляет собой 64-разрядное целое число, представляющее местоположение в памяти.

То же самое с ls, grep и wc.Они имеют тип char **, который представляет собой просто 64-битное целое число, представляющее местоположение в памяти.

cmd[0] = ls говорит, что начинается с адреса cmd, опережая на размер указателей 0 char **(т. е. 0), а затем назначьте указатель char **, содержащийся в ls, на это местоположение.Таким образом, если cmd находится в ячейке памяти 100, это записывает от 100 до 107.

cmd[1] = grep говорит, что нужно начинать с адреса cmd, 100. Перемещение по размеру указателей 1 char **, 8. Затем назначьте указатель char **, содержащийся в grep, этому месту.Таким образом, 100 + 8 - это 108. Затем запишите 8 байтов в числа от 108 до 115.

И cmd[2] = grep записывает 64-разрядное число в grep в ячейку памяти 100 + (2 * 8) или от 116 до 123.

И так далее.Это работает таким образом для любого массива указателей.Или указатели на указатели.Это просто набор целых чисел.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...