Двойной указатель для argv - PullRequest
1 голос
/ 17 июня 2019

Я пытаюсь создать argv для нового процесса (пытаюсь использовать execvp), и я проверил страницу руководства execvp, в которой говорится, что ей нужно char * const argv [].

Я предполагаю, что это указатель на массив указателей на символы. Так можно ли передать двойной указатель char на этот аргумент?

По сути, я пытаюсь сделать следующее (argvcounter - количество аргументов. ex) cat a -> argvcount = 2)

int argvcount;
char **argv;
...
argv = malloc(sizeof(char*)*(argvcount+1));
for (int i = 0; i<argvcount; i++){
    argv[i] = some char pointer;
}
argv[-1] = NULL; 

Я не уверен насчет последней строки. Я устанавливаю последний элемент в NULL, так как последний элемент массива аргументов должен быть NULL.

Можно ли передать этот argv в execvp?

Спасибо.

Ответы [ 2 ]

1 голос
/ 17 июня 2019

В соответствии со стандартом C (5.1.2.2.1 Запуск программы, стр. # 2)

— argv[argc] shall be a null pointer

Итак, вы должны написать

argv[argvcount] = NULL; 

Это утверждение

argv[-1] = NULL; 

не имеет смысла и приводит к неопределенному поведению.

Я предполагаю, что это указатель на массив указателей на символы.Так можно ли передать двойной указатель char на этот аргумент?

Указатель массива с редкими исключениями неявно преобразуется в указатель на его первый элемент.

Так что если, например, выимеет массив, подобный этому

char * argv[argvcount];

, затем передается функции, которую он преобразует в указатель на свой первый элемент и имеет тип char **.

С другой стороны, эти объявления функций

void f( char *a[] );

и

void f( char **a );

эквивалентны, поскольку компилятор корректирует тип параметра, объявленного как массив, в соответствии с типом указателя на объект типа элемента массива.

0 голосов
/ 17 июня 2019

нужно char *const argv[].Я предполагаю, что это указатель на массив указателей на символы.

Нет, это массив указателей char* const.Это может помочь при чтении этих объявлений справа налево:

  • [] Массив (неизвестного размера) ...
  • argv ... named argv ...
  • const ... of const ...
  • * ... указатели ...
  • char ... на символ.

На простом английском языке: массив (неизвестного размера) с именем argv, предназначенный только для чтения указателей на символ.

Так что можно передать двойной указатель char на этот символАргумент?

Обратите внимание на тонкую разницу между аргументами и параметрами.Параметр, относящийся к переменной в объявлении функции, аргумент, относящийся к вещам, которые вы передаете функции на стороне вызывающей стороны.Здесь это имеет значение.

Поскольку функция, принимающая параметр типа char *const argv[], будет автоматически корректировать этот параметр компилятором в указатель на первый элемент (иногда называемый «распадом массива»).Вот почему нам не нужно указывать размер массива - он будет «затухать» независимо от размера массива.

Первый элемент - это char*const, а указатель на такой элемент имеет тип char*const*, так что именно этого типа ожидает функция.Указатель на константный указатель на тип char - на втором уровне косвенности сам указатель не может быть изменен.

Как это бывает, char** - это тип, который может быть неявно преобразован в char*const*, посколькупоследний является «квалифицированной» версией первого - это тот же тип, но с «больше const в нужных местах».Как правило, любой type* может быть преобразован в type*const.

Если бы параметр был const char* argv[], было бы невозможно использовать char**, потому что в этом случае const принадлежитк указанному типу, а не к указателю.


Как уже отмечалось, обратите внимание, что argv[-1] = NULL; - это нонсенс, оно должно быть argv[argvcount] = NULL;

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