开发者

C++ Array bound exception on overflow - "cout" and no "cout"

#include <iostream>

int main()
{
  int array1[10] = {0};
  char* array2[10] = {'\0'};

  for (int i = 0; i <= 100; i++)
  {
    std::cout << arr开发者_如何转开发ay1[i];   // This does not crash 
    //std::cout << array2[i]; // This crashes
    array1[i]; // Wont crash here
    array2[i]; // nor here, Why? because there is no cout??
  }
  return 0;
}

Ok so for the people answering here, i know i deliberately made an overflow for the arrays. So why does the program crash on "cout", but not otherwise??

Thanks!


Given that the value is unused, it is probably optimized away by the compiler and never really retrieved at run time.


EDIT: In response to the changed version of the question, the reason it crashes for array2 but not array1 is that (at least under MSVC) the operator<< for char* tries to get the length of the pointed-to string and ends up dereferencing a NULL pointer. You get the same behaviour if you do:

std::cout << (char*)NULL;

The crash in this case is not caused by the out-of-bounds access, but by a null pointer dereference.


Despite that, further to what @UncleZeiv said, you can tell what code's actually doing by looking at the disassembly output from your compiler. For instance, on VC++ 2008, I get:

        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?

In other words, the compiler is not outputting any instructions when you're not doing anything with array1[i] and array2[i] (the two instructions are no-ops), so the program doesn't crash even though you're theoretically referencing something beyond the bounds of the array and invoking undefined behaviour.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜