溢出时C ++数组绑定异常 - “cout”而没有“cout”

时间:2010-12-19 11:50:56

标签: c++ arrays crash

#include <iostream>

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

  for (int i = 0; i <= 100; i++)
  {
    std::cout << array1[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;
}

好的,对于在这里回答的人,我知道我故意为阵列做了一个溢出。那么为什么程序会在“cout”上崩溃,而不是其他?

谢谢!

2 个答案:

答案 0 :(得分:5)

鉴于该值未被使用,它可能会被编译器优化掉,并且在运行时从未真正检索过。

答案 1 :(得分:2)

编辑:在回答问题的更改版本时,array2而不是array1崩溃的原因是(至少在MSVC下){{ 1}} for operator<<尝试获取指向字符串的长度,最后取消引用char*指针。如果你这样做,你会得到同样的行为:

NULL

这种情况下的崩溃不是由越界访问引起的,而是由空指针引用引起的。


尽管如此,除了@UncleZeiv所说的,你可以通过查看编译器的反汇编输出来判断代码实际上在做什么。例如,在VC ++ 2008上,我得到:

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

换句话说,当你没有对 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]做任何事情时,编译器没有输出任何指令(两条指令都是无操作),所以程序不会崩溃即使你理论上引用了超出数组边界的东西并调用未定义的行为。