Frage

Ich schreibe einen Test, der den Inhalt von argv[0] – die Adresse des Parameters der Hauptfunktion – wie folgt ausgibt:

printf("%p\n",argv[0]);

Ich habe das Programm mit Visual Studio 2008 unter Windows 7 kompiliert.

Dann habe ich das Programm 1000 Mal ausgeführt und die Ergebnisse in eine Datei ausgegeben.Dadurch ändert sich die Adresse von argv[0], einige Adressen sind jedoch gleich und wiederholen sich etwa zehnmal.

Warum ändert sich die Adresse des Parameters der Hauptfunktion jedes Mal?

War es hilfreich?

Lösung

Interessante Frage, sehe ich nur sehr wenige oder gar keine Gründe für die Nicht-Determinismus, dass in eigenen Adressraum des Programms. Aber ich werde Ihnen sagen, was ich weiß.

Als erstes argv zugeordnet, erstellt und initialisiert sich nicht durch Fenster, sondern durch STDC Laufzeit. Was wiederum wirft eine andere Frage - nicht lpCmdLine Parameter von winmain auch ändern? Im moment gibt es mehrere andere Variablen auf dem gleichen Heap zugewiesen, wahrscheinlich Umgebung Vars werden ebenfalls kopiert. Einer von ihnen muss eine Größe haben, je nach dem Fall der Ausführung.

Wie auch immer, warum grübeln Blackbox? Wo ist dein Disassembler, Soldat?

Andere Tipps

argc und argv sollten auf den Stapel gelegt werden, bevor die von der Hauptroutine der binären ausführbaren beginnen. Eigentlich denke ich, dass argv dynamisch irgendwo in dem Heap zugeordnet wird und dann wird der Zeiger auf den Stapel gelegt.

Das bedeutet, dass der Haufen Allocator ist derjenige, der kümmert sich um, wo die Daten zugeordnet ist und aus diesem Grund ändert jedes Mal (es von der Politik abhängt) .. Ihr Programm wird dem OS bitten, den Raum für die Argumente zuweisen (man denke etwa durch malloc vorbei), so kann es interne Entscheidungen sein, hergestellt nach etwas (wie die ASLR sie sprachen)

Hier ist zunächst einmal der Sprachstandard (n1256) muss sagen:

5.1.2.2.1 Programmstart
...
2 Wenn sie deklariert werden, müssen die Parameter für die Hauptfunktion den folgenden Einschränkungen befolgen:

  • Der Wert von argc soll nicht negativ sein.

  • argv[argc] soll ein Nullzeiger sein.

  • Wenn der Wert von argc ist größer als Null, die Array-Mitglieder argv[0] durchargv[argc-1] Inklusive müssen Zeiger auf Zeichenfolgen enthalten, die vor dem Programm Startup implementiert werden.Die Absicht ist es, die vor dem Programm Startup von anderen Gegenden in der gehosteten Umgebung festgelegten Programminformationen zu liefern.Wenn die Wirtsumgebung nicht in der Lage ist, Saiten mit Buchstaben in Großbuchstaben und Kleinbuchstaben zu liefern, muss die Implementierung sicherstellen, dass die Zeichenfolgen in Kleinbuchstaben empfangen werden.

  • Wenn der Wert von argc ist größer als Null, die Zeichenfolge, auf die gezeigt wird argv[0]repräsentiert die Programmname; argv[0][0] soll der Nullcharakter sein, wenn der Programmname nicht in der Hostumgebung verfügbar ist.Wenn der Wert von argc ist größer als eins, auf die Saiten hingewiesen durch argv[1] durch argv[argc-1]repräsentieren die Programmparameter.

  • Die Parameter argc Und argv und die Zeichenfolgen, auf die die zeigt argv Array ist durch das Programm verändert und behält ihre zuletzt gelagerten Werte zwischen Programmstart und Programmabschluss bei.

Der letzte Punkt ist der interessanteste in Bezug auf Wo die übergebenen String-Argumente main sind gelagert.Sie müssen veränderbar sein und eine statische Ausdehnung haben, wodurch ihre Position im Speicher eingeschränkt wird.Es gibt jedoch keine Anforderung seitens der Sprachdefinition, dass sie sich jedes Mal, wenn das Programm ausgeführt wird, am selben Ort befinden.

Ich habe MSDN flüchtig durchsucht, um zu sehen, ob dort etwas explizites steht, habe aber noch nichts gefunden.Es kommt wahrscheinlich auf ASLR an, wie in den Kommentaren zum OP erwähnt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top