Вам разрешено изменять argc
и argv
, но это не означает, что C внезапно обрабатывает (пере) распределение этих переменных для вас.argv
будет массивом типа char* argv[argc];
.Он будет содержать столько указателей, сколько argc
говорит, что содержит, не больше, не меньше.Точно так же длина каждой строки, на которую указывает argv[i]
, равна длине, которую передал вызывающий.
Пример:
myprog.exe foo
- Это означает, что
argc == 2
и argv
будет иметь длину 2. Это не может быть изменено вашей программой. argv[0]
будет указывать на изменяемую строку "myprog.exe"
, размер 10 + 1 = 11 байтов.Вы можете изменить содержимое, но не хранить там ничего длиннее 11 байт. argv[1]
будет указывать на строку "foo"
, размер 3 + 1 = 4 байта.Вы можете изменить содержимое, но не хранить там ничего длиннее 4 байт.
(Любопытство: это совершенно нормально и, пожалуй, самый правильный способ определить argv
как VLA, например:
int main (int argc, char* argv[argc])
, потому что argv
распадается на char**
в любом случае.)
То, что все сказанное, изменение argc
и argv
, хотя и разрешено стандартом C, ужасноплохая практика.Не делай этого.Вместо этого вы должны использовать локальную переменную и позволить ей ссылаться на argv
, где это необходимо.Пример:
int main (int argc, char* argv[])
{
const char* argstr [12] =
{
"str0",
"str1",
"str2",
"str3",
"str4",
"str5",
"str6",
"str7",
"str8",
"str9",
"str10",
"str11",
};
for(int i=0; i<argc; i++)
{
argstr[i] = argv[i];
}
/* always use argstr here, never argv */
return 0;
}