Почему адрес параметра главной функции меняется каждый раз? - PullRequest
2 голосов
/ 17 ноября 2010

Я пишу тест, который печатает содержимое argv [0] - адрес параметра основной функции следующим образом:

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

Я скомпилировал программу с Visual Studio 2008 на Windows 7.

Затем я 1000 раз выполнил программу, которая выводит результаты в файл. В результате адрес argv [0] изменяется, однако некоторые адреса совпадают и повторяются примерно 10 раз.

Почему адрес параметра главной функции меняется каждый раз?

Ответы [ 3 ]

2 голосов
/ 17 ноября 2010

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

Это означает, что распределитель кучи - это тот, который заботится о том, где размещены данные, и этопочему он меняется каждый раз (это зависит от политики) .. ваша программа попросит ОС выделить место для аргументов (подумайте о прохождении через malloc), чтобы можно было сделать внутренний выбор в соответствии с чем-то (например, ASLR)о чем они говорили)

1 голос
/ 17 ноября 2010

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

Сначала argv выделяется, создается и инициализируется не окнами, а средой выполнения stdc.Что, в свою очередь, поднимает другой вопрос - изменяется ли параметр lpCmdLine в winmain?Есть несколько других переменных, размещенных в одной и той же куче, возможно, переменные среды также копируются.Один из них должен иметь размер в зависимости от экземпляра выполнения.

Во всяком случае, почему черный ящик размышляет?Где твой дизассемблер, солдат?

0 голосов
/ 17 ноября 2010

Прежде всего, вот что говорит языковой стандарт ( n1256 ):

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

  • Значение argc должно быть неотрицательным.

  • argv[argc] должен быть нулевым указателем.

  • Если значение argc больше нуля, элементы массива argv[0] через argv[argc-1] включительно должен содержать указатели на строки, которые даны значения, определенные реализацией средой хоста до запуска программы. намерение состоит в том, чтобы предоставить программе информацию, определенную до ее запуска из другого места в размещенной среде. Если среда хоста не способна предоставление строк с буквами в верхнем и нижнем регистре, реализация убедитесь, что строки получены в нижнем регистре.

  • Если значение argc больше нуля, строка, на которую указывает argv[0] представляет имя программы ; argv[0][0] должен быть нулевым символом, если Имя программы недоступно в хост-среде. Если значение argc больше единицы строки, на которые указывают argv[1] до argv[argc-1] представляют программные параметры .

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

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

Я сделал краткий поиск в MSDN, чтобы выяснить, говорят ли они что-нибудь явное, но еще ничего не нашел. Это, вероятно, сводится к ASLR, как упоминалось в комментариях к ФП.

...