Почему `optarg` не перезаписывается? - PullRequest
0 голосов
/ 24 августа 2018

Я новичок в getopt(3), посмотрел несколько примеров и наткнулся на этот .

Эти строки

  case 'c':
    cvalue = optarg;
    break;

мне показалось странным, потому что содержимое optarg не копируется в cvalue, они просто копируют указатель. Но это работает:

$ testopt -a -b -c foo
aflag = 1, bflag = 1, cvalue = foo

Я ожидал, что optarg будет перезаписан вторым вызовом getopt(), поэтому я написал свою собственную программу на основе примера. Удивительно, но optarg не перезаписывается.

$ testopt -p -f me -t you
pflag = 1, from = me, to = you

Работает ли это последовательно или я всегда должен копировать / дублировать?
Должен ли я позаботиться о free() всё, что вернулось в optarg?
Мне просто везет, а realloc() из optarg не присваивается одному и тому же адресу?

Ответы [ 2 ]

0 голосов
/ 24 августа 2018

Из руководств GNU :

Если опция имеет аргумент, getopt возвращает аргумент, сохраняя его в переменной optarg.Обычно вам не нужно копировать строку optarg , поскольку она является указателем на исходный массив argv , а не на статическую область, которая может быть перезаписана.

Вот почемуего не нужно копировать или выделять. Документация POSIX требует этого для optarg.

0 голосов
/ 24 августа 2018

optarg указывает элемент в argv. Если вы можете гарантировать, что argv не исчезнет и не будет затронут какими-либо другими частями кода, у вас все получится. Поскольку argv обычно начинается с начала main до конца программы, вы можете безопасно кешировать эти указатели.

Но обработайте значение optarg как const char*. То есть не пытайтесь делать с этой памятью ничего, кроме ссылки на нее или копирования исходной строки. Попытка сделать что-то вроде strcat на указателе в лучшем случае небезопасна.

...