Frage Ist es sicher, den Argv-Zeiger global zu verwenden?


Ist es sicher das zu benutzen? argv Zeiger global? Oder gibt es einen Umstand, wo es ungültig werden könnte?

h.: ​​Ist dieser Code sicher?

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

29
2017-07-24 07:58


Ursprung


Antworten:


Ja, es ist sicher zu benutzen argv global; Sie können es so verwenden, wie Sie es verwenden würden char** in deinem Programm. Der C99-Standard spezifiziert dies sogar:

Die Parameter argc und argv und die Saiten, auf die der argv Das Array soll durch das Programm änderbar sein und seine zuletzt gespeicherten Werte zwischen Programmstart und Programmbeendigung behalten.

Der C ++ - Standard hat keinen ähnlichen Absatz, aber derselbe ist implizit ohne gegenteilige Regel.

Beachten Sie, dass C ++ und C verschiedene Sprachen sind und Sie sollten nur eine auswählen, um Ihre Frage zu stellen.


39
2017-07-24 08:04



Es sollte sicher sein, solange main() Funktion wird nicht beendet. Ein paar Beispiele für Dinge, die danach passieren können main() Ausgänge sind:

  1. Destruktoren von globalen und statischen Variablen
  2. Threads, die länger als main()

Gelagert argv darf nicht in denen verwendet werden.

Die Referenz sagt nichts, was einen Grund zu der Annahme geben könnte, dass die Lebensdauern der Argumente ausreichen main() Funktion unterscheidet sich von den allgemeinen Regeln für die Lebensdauer von Funktionsargumenten.

So lange wie argv Da der Zeiger selbst gültig ist, muss die C / C ++ - Laufzeit garantieren, dass der Inhalt, auf den dieser Zeiger zeigt, gültig ist (natürlich, wenn etwas den Speicher nicht beschädigt). Daher muss es sicher sein, den Zeiger und den Inhalt so lange zu verwenden. Nach main() zurück, gibt es keinen Grund für die C / C ++ - Laufzeit, den Inhalt auch weiterhin gültig zu halten. Das obige Argument gilt also sowohl für den Zeiger als auch für den Inhalt, auf den es zeigt.


17
2017-07-24 08:03



ist es sicher, den Argv-Zeiger global zu verwenden

Dies erfordert ein wenig mehr Klärung. Als die C11 Spezifikation sagt in Kapitel §5.1.2.2.1, Programmstart

[..] .. mit zwei Parametern (hier bezeichnet als argc und argv, obwohl irgendwelche Namen verwendet werden können, da sie lokal für die Funktion sind, in der sie deklariert sind)

Das heißt, die Variablen selbst haben a Umfang begrenzt auf main(). Sie sind nicht global sich.

Wiederum sagt der Standard,

Die Parameter argc und argv und die Strings, auf die das argv-Array zeigt, sollen durch das Programm modifizierbar sein und ihre zuletzt gespeicherten Werte zwischen Programmstart und Programmbeendigung behalten.

Das heißt, die Lebenszeit dieser Variablen sind bis main() beendet die Ausführung.

Wenn Sie also eine globale Variable verwenden, von der der Wert übernommen werden soll main(), können Sie diese Globals verwenden, um auf dieselben in jeder anderen Funktion (en) zuzugreifen.


8
2017-07-24 08:18



Dieser Thread auf der comp.lang.c.moderated Newsgroup diskutiert das Problem ausführlich aus einer C-Standard-Sicht, einschließlich einer Zitation, die zeigt, dass der Inhalt der Argv-Arrays (anstatt der Argv-Zeiger selbst, wenn Sie zum Beispiel eine Adresse genommen &argv und gespeichert, dass) zuletzt bis "Programmbeendigung", und eine Behauptung, dass es "offensichtlich" ist, dass Programmbeendigung noch nicht in einer Weise aufgetreten ist, die relevant ist, während die atexit-registrierten Funktionen ausgeführt werden:

Das Programm wurde nicht während atexit-registriert beendet   Funktionsverarbeitung. Das fanden wir ziemlich offensichtlich.

(Ich bin nicht sicher, wer Douglas A. Gwyn ist, aber es klingt wie "wir" bedeutet das C-Standard-Komitee?)

Der Kontext der Diskussion bezog sich hauptsächlich auf das Speichern einer Kopie des Zeigers argv[0] (Programmname).

Der relevante C-Standardtext ist 5.1.2.2.1:

Die Parameter argc und argv und die Strings, auf die die   argv array soll durch das Programm änderbar sein und ihre   Zuletzt gespeicherte Werte zwischen Programmstart und Programm   Beendigung.

Natürlich ist C ++ kein C, und sein Standard kann sich bei diesem Problem subtil unterscheiden oder ihn nicht ansprechen.


5
2017-07-24 12:41



Sie können sie entweder als Parameter übergeben oder speichern global variables. Solange du nicht zurückkommst main und versuche sie in einem zu verarbeiten atexit Handler oder der Destruktor einer Variablen im globalen Gültigkeitsbereich, existieren sie noch und können von jedem Bereich aus zugreifen.


3
2017-07-24 08:07



Ja, es ist sicher für Ether C oder C ++, weil dort kein Thread nach main beendet wurde.


2
2017-07-24 08:29