Подтвердить что ты не робот

Безопасно ли использовать указатель argv глобально?

Безопасно ли использовать указатель argv глобально? Или есть обстоятельства, когда это может стать недействительным?

i.e: Безопасен ли этот код?

char **largs;
void function_1()
{
    printf("Argument 1: %s\r\n",largs[1]);
}
int main(int argc,char **argv)
{
    largs = argv;
    function_1();
    return 1;
}
4b9b3361

Ответ 1

Да, безопасно использовать argv глобально; вы можете использовать его, как если бы вы использовали любой char** в своей программе. Стандарт C99 даже определяет это:

Параметры argc и argv, а строки, на которые указывает массив argv, могут быть модифицированы программой и сохраняют их последние сохраненные значения между запуском программы и завершением программы.

Стандарт С++ не имеет аналогичного абзаца, но то же самое подразумевается без правила обратного.

Обратите внимание, что С++ и C - это разные языки, и вы должны просто выбрать один, чтобы задать свой вопрос.

Ответ 2

Он должен быть безопасным, если функция main() не выходит. Несколько примеров вещей, которые могут произойти после выходов main():

  • Деструкторы глобальных и статических переменных
  • Потоки, длина которых превышает main()

Сохраненный argv не должен использоваться в них.

Ссылка не говорит ничего, что дало бы основание предположить, что время жизни аргументов функции main() отличается от общие правила для времени жизни аргументов функции.

Пока выполняется сам указатель argv, среда выполнения C/С++ должна гарантировать, что контент, на который указывает этот указатель, действителен (конечно, если только что-то не повреждает память). Поэтому должно быть безопасно использовать указатель и контент, который долго. После возврата main() нет причин для того, чтобы среда выполнения C/С++ сохраняла значение. Таким образом, приведенные выше рассуждения применимы как к указателю, так и к содержанию, на которое он указывает.

Ответ 3

безопасно использовать глобальный указатель argv

Это требует немного большего разъяснения. Поскольку спецификация C11 говорит в главе §5.1.2.2.1, запуск программы

[..].. с двумя параметрами (называемыми здесь argc и argv, хотя любые имена могут использоваться, поскольку они являются локальными для функции, в которой они объявлены)

Это означает, что сами переменные имеют область, ограниченную main(). Они не являются глобальными.

Снова стандарт говорит:

Параметры argc и argv, а строки, на которые указывает массив argv, могут быть модифицированы программой и сохраняют свои последние сохраненные значения между запуском программы и завершением программы.

Это означает, что продолжительность жизни этих переменных до завершения выполнения main() завершается.

Итак, если вы используете глобальную переменную для хранения значения из main(), вы можете безопасно использовать эти глобальные переменные для доступа к ним в любых других функциях.

Ответ 4

Этот поток в группе сообщений comp.lang.c.moderated подробно обсуждает проблему со стандартной точки C, включая цитату показывая, что содержимое массивов argv (а не самого указателя argv, если, например, вы взяли адрес &argv и сохранили его) до тех пор, пока не завершится "завершение программы", и утверждение, что "очевидно", что завершение программы не но все же произошло таким образом, как это происходит при выполнении функций, выполняемых atexit:

Программа не завершена во время регистрации atexit обработки функций. Мы думали, что это было довольно очевидно.

(Я не уверен, кто такой Дуглас А. Гвин, но это звучит так, как будто "мы" - это стандартный комитет С?)

Контекст обсуждения в основном касался хранения копии указателя argv[0] (имя программы).

Соответствующий стандартный текст C - это 5.1.2.2.1:

Параметры argc и argv и строки, на которые указывает argv-массив должен быть модифицирован программой и сохранить их последние сохраненные значения между запуском программы и программой прекращение.

Конечно, С++ не является C, и его стандарт может незначительно отличаться по этой проблеме или не обращаться к нему.

Ответ 5

Вы можете передать их как параметры или сохранить их в global variables. Пока вы не вернетесь из main и попробуйте обработать их в обработчике atexit или деструкторе переменной в глобальной области, они все еще существуют и будут доступны для доступа из любой области.

Ответ 6

да, это безопасно для эфира C или С++, потому что ни один поток после завершения main не был завершен.