如果在char数组中插入0(\ 0)(超出范围索引),则检出超出条件

时间:2017-06-09 04:15:36

标签: c++

我只是从基础知识中学习C ++,并且在数组中学到了在C ++中没有对数组进行绑定检查(例如:int data [10],访问数据[12]编译器不会产生任何错误并给出运行时的值,如果可以访问内存)

在练习int和char数组时,我注意到以下区别:

char char_data[10];//char array case
char_data[1] = 'h';
char_data[15] = 'v';//line 1
char_data[11] = '\0';//line 2


int int_data[10];//int array case
int_data[1] = 10;
int_data[15] = 150;//line 3
int_data[11] = 0;//line 4

当我使用 MSVC ++ 14.0 main中运行上述代码时,代码编译正常(因为没有在C ++中进行绑定检查),但在char array case中,代码是崩溃/中断line 2我将元素等同于'\0'(当索引超出范围时,它不考虑索引而是值('\0'))并且生成的程序集为如下:

    10:     data[15] = 'v'; //(no bound check here)
00CF1FE5 B8 01 00 00 00       mov         eax,1  
00CF1FEA 6B C8 0F             imul        ecx,eax,0Fh  
00CF1FED C6 44 0D EC 76       mov         byte ptr data[ecx],76h  

11:     data[11] = '\0';//line 2 (bound check here)
00AF1FFA 89 8D F0 FE FF FF    mov         dword ptr [ebp-110h],ecx  
00AF2000 83 BD F0 FE FF FF 0A cmp         dword ptr [ebp-110h],0Ah  
00AF2007 73 02                jae         main+5Bh (0AF200Bh)  
00AF2009 EB 05                jmp         main+60h (0AF2010h)  
00AF200B E8 6C F1 FF FF       call        ___report_rangecheckfailure        (0AF117Ch)  
00AF2010 8B 95 F0 FE FF FF    mov         edx,dword ptr [ebp-110h]  
00AF2016 C6 44 15 EC 00       mov         byte ptr data[edx],0  

此处,如果值不是'\0',则不会为rangecheck failure生成任何程序集。但是,如果我考虑int的情况,当超出范围index 0'\0'的值只是0)时,它不会检查范围。我无法理解这种行为。

这是编译器相关的还是这种行为(绑定检查值是否为\0)在所有编译器中是否相同?

请帮助!!!

1 个答案:

答案 0 :(得分:1)

那么,你想要对数组进行边界检查吗?有一个解决方案,就是使用std::array,它是标准库的一部分,因为C ++ 11通过标题<array>。如果将数组定义为:

std::array<int, 10> data;

然后可以像往常一样使用operator[]实现所有常用的数组访问,但是你也得到了at函数(documentation here),它将执行范围测试并抛出{ {1}}失败。

std::out_of_range

如果您愿意,欢迎您在try-block中捕获异常。如果你没有抓住,那么你会在导致错误的确切位置得到一个很好的程序崩溃。这比未定义的行为更好。

当然,在普通情况下,你真的不应该使用异常抛出边界检查。特别是在阵列上。你知道它的大小,所以不要做愚蠢的事情,比如访问有效范围之外的值。