2012-06-27 3 views
9

Возможно, я просто дамп для поиска в Google, но я всегда думал, что массивы char получают только нуль, завершаемые литеральной инициализацией (char x[]="asdf";), и немного удивлены, когда я увидел, что это, похоже, не так.Все ли массивы char автоматически заканчиваются на нуль?

int main() 
{ 
    char x[2]; 
    printf("%d", x[2]); 
    return 0; 
} 

Выход: 0

В случае, если не массив, объявленный как размер = 2 * символ на самом деле получить размер 2 символов? Или я делаю что-то не так? Я имею в виду, что не редко используется массив символов как простой массив символов, а не как строка, или это так?

ответ

20

Вы получаете доступ к неинициализированному массиву за пределами его границ. Это двойное неопределенное поведение, все может случиться, даже получив 0 как выход.

В ответе на ваш реальный вопрос: только строковые литералы получить завершающего нуля, и это означает, что char x[]="asdf" является массивом 5 элементов.

+0

Я тоже об этом подумал, поэтому я попытался создать массивы разных размеров, а за массивом всегда следует 0. (0, показанное в моем примере, не сопровождалось 0, а массив с размером 3 * char в том же месте был) – user1329846

+0

@ user1329846: Независимо от того, что хранится в памяти после окончания массива, до компилятора вы получаете 0, но можете также получить любое другое число, как говорит стандарт, если вы попытаетесь прочитать, что расположение всех ставок выключено. Позвольте мне сделать это ясно: даже если вам повезло, что вы всегда получаете 0s, ваш код по-прежнему вызывает неопределенное поведение_ и может выйти из строя в любое время. –

+0

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

3

char arrays не автоматически NULL завершено, только строковые литералы, например. char *myArr = "string literal";, а некоторые указатели строковых символов возвращены из методов строки stdlib.

C не делает проверку границ. Таким образом, массив, объявленный как размер 2*char, дает вам 2 слота памяти, которые вы можете использовать, но у вас есть свобода ходить по всей памяти по обе стороны от нее, читать и писать и тем самым ссылаться на неопределенное поведение. Вы можете увидеть там 0 байт. Вы можете написать array[-1] и свернуть свою программу. Вы несете ответственность за отслеживание размера вашего массива и избегаете касания памяти, которую вы не выделили.

Обычно используется массив символов как простой массив символов, то есть, помимо строки C, например, для хранения любого произвольного буфера необработанных байтов.

0

t Если это массив размера 2, то последний случай t[2 - 1] = t[1] и не 2. t[2] находится вне границ.