РЕДАКТИРОВАТЬ: В ответ на измененную версию вопроса причина, по которой он падает для array2
, но не array1
, заключается в том, что (по крайней мере, в MSVC) operator<<
для char*
пытается получить длину указанной строки и в итоге разыменовывает указатель NULL
. Вы получаете такое же поведение, если вы делаете:
std::cout << (char*)NULL;
Сбой в этом случае вызван не за пределами доступа, а разыменованием нулевого указателя.
Несмотря на это, в дополнение к тому, что сказал @UncleZeiv, вы можете узнать, что на самом деле делает код, посмотрев выходные данные дизассемблирования вашего компилятора. Например, на VC ++ 2008 я получаю:
std::cout<<array1[i]; //--> This crashes
00B2151E mov esi,esp
00B21520 mov eax,dword ptr [i]
00B21523 mov ecx,dword ptr array1[eax*4]
00B21527 push ecx
00B21528 mov ecx,dword ptr [__imp_std::cout (0B2A334h)]
00B2152E call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0B2A318h)]
00B21534 cmp esi,esp
00B21536 call @ILT+405(__RTC_CheckEsp) (0B2119Ah)
std::cout<<array2[i]; //--> So does this
00B2153B mov eax,dword ptr [i]
00B2153E mov ecx,dword ptr array2[eax*4]
00B21542 push ecx
00B21543 mov edx,dword ptr [__imp_std::cout (0B2A334h)]
00B21549 push edx
00B2154A call std::operator<<<std::char_traits<char> > (0B2114Fh)
00B2154F add esp,8
array1[i]; // But not this one
array2[i]; // nor this, Why?
Другими словами, компилятор не выводит никаких инструкций, когда вы ничего не делаете с array1[i]
и array2[i]
(эти две команды не используются), поэтому программа не падает, даже если вы ' теоретически ссылается на что-то за пределами массива и вызывает неопределенное поведение.