argc / argv влияет на нулевой байт в массивах?

Почему следующее:

#include <stdio.h>

int main(int argc, char *argv[])
{
     char array[3] = {'1', '2', '3'};
     printf("%s\n", array);

     return 0;
}

производит 1238À§Wˇ ("123" + несколько случайных символов), как и ожидалось, в то же время код:

int main(void)

вместо argc, argv производит: 123 (несмотря на отсутствие места для нулевого байта).

Как получается, что отсутствие места для нулевого байта в array с void не имеет значения?

2 ответа

Решение

Когда вы делаете это:

char array[3] = {'1', '2', '3'};
printf("%s\n", array);

Вы вызываете неопределенное поведение, потому что массив символов не завершен NUL. Вы можете получить "123", или вообще ничего, или что-то подобное, или это может варьироваться в зависимости от любых произвольных условий.

В вашем конкретном случае, просто обоснованное предположение, после локальной переменной array это, вероятно, память для аргументов функции, и те, argc а также argv, В зависимости от фактических аргументов main и даже значения времени выполнения, переданные в программу, байты на этих позициях памяти будут различаться. И иногда они должны иметь NUL-байт в нужном месте и влиять на вывод вашей программы.

Во всяком случае, мой совет не переосмыслить случаи UB. Их лучше всего считать неопределенными.

Вы не предоставляете нулевой байт конца строки (EOS), поэтому printf продолжает идти, пока он [просто не случится], чтобы найти один (то есть символы мусора).

Любое из следующего будет работать:

char array[4] = { '1', '2', '3', '\0' };
char array[4] = { '1', '2', '3' };
char array[4] = "123";
char array[] = { '1', '2', '3', '\0' };
char array[] = "123";
char *array = "123";
Другие вопросы по тегам