msvcr90.dll!_invalid_parameter_noinfo() Line 125 + 0xc bytes 的排错

来源:互联网 发布:exec linux脚本 用法 编辑:程序博客网 时间:2024/05/14 14:44

msvcr90.dll!_invalid_parameter_noinfo() Line 125 + 0xc bytes 的排错

 1475人阅读 评论(1) 收藏 举报
vectordebuggingstringiteratormicrosoftreference

如题。当dump定位到这个地方时,有理由怀疑是下标访问string时越界了。

我们先看Checked Iterators中的例子。

[cpp] view plaincopy
  1. // compile with: /EHsc  
  2. #define _SECURE_SCL 1  
  3. #define _SECURE_SCL_THROWS 1  
  4. #include <vector>  
  5. #include <iostream>  
  6. using namespace std;  
  7. int main() {  
  8.    vector v;  
  9.    v.push_back(67);  
  10.    int i = v[0];  
  11.    cout << i << endl;  
  12.   
  13.    try {  
  14.       i = v[1];  
  15.    }  
  16.    catch (std::out_of_range) {  
  17.       cout << "invalid container access" << endl;  
  18.    }  
  19. };  
这里vector访问越界,catch会抓到异常。但是如果把vector换成string:

[cpp] view plaincopy
  1. #include <string>   
  2. int main() {   
  3.     string str = "";   
  4.     char s;   
  5.     try {   
  6.         s = str[1];   
  7.     }   
  8.     catch (std::out_of_range) {   
  9.         cout << "invalid container access" << endl;   
  10.     }   
  11. };  
 

却什么也catch不到,Release版直接crash。通过dump定位到如题的错误。为什么呢?

看一下string::operator[]()的实现。它在Microsoft Visual Studio 9.0/VC/crt/src/xstring中:

[cpp] view plaincopy
  1.     reference __CLR_OR_THIS_CALL operator[](size_type _Off)   
  2.         {    // subscript mutable sequence  
  3. #if _HAS_ITERATOR_DEBUGGING   
  4.         // skip debug checks if the container is initizialed with _IGNORE_MYITERLIST   
  5.         if (this->_Myfirstiter != _IGNORE_MYITERLIST)   
  6.             {   
  7.             if (_Mysize < _Off)   
  8.                 {   
  9.                 _DEBUG_ERROR("string subscript out of range");   
  10.                 _SCL_SECURE_OUT_OF_RANGE;   
  11.                 }   
  12.             }   
  13. #else   
  14.         _SCL_SECURE_VALIDATE_RANGE(_Off <= _Mysize);   
  15. #endif /* _HAS_ITERATOR_DEBUGGING */  
  16.         return (_Myptr()[_Off]);   
  17.         }  
 

_SCL_SECURE_VALIDATE_RANGE是在/VC/include/yvals.h中定义的:

[cpp] view plaincopy
  1. #define _SCL_SECURE_VALIDATE_RANGE(cond)                /   
  2.     {                                                    /   
  3.         if (!(cond))                                    /   
  4.         {                                                /   
  5.             _ASSERTE((#cond, 0));                        /   
  6.             _SCL_SECURE_OUT_OF_RANGE_NO_ASSERT;            /   
  7.         }                                                /   
  8.         __analysis_assume(cond);                        /   
  9.     }  
 

只要能走到红色位置,就可以和vector一样抛出out_of_range异常,可惜却没有。经跟踪,发现是_SECURE_SCL_THROWS宏在搞鬼。

[cpp] view plaincopy
  1. #if _SECURE_SCL_THROWS  
  2. #define _SCL_SECURE_INVALID_ARGUMENT_NO_ASSERT        _Xinvarg()   
  3. #define _SCL_SECURE_OUT_OF_RANGE_NO_ASSERT            _Xran()  
  4. #else /* _SECURE_SCL_THROWS */  
  5. #define _SCL_SECURE_INVALID_ARGUMENT_NO_ASSERT        _SCL_SECURE_INVALID_PARAMETER("invalid argument")   
  6. #define _SCL_SECURE_OUT_OF_RANGE_NO_ASSERT            _SCL_SECURE_INVALID_PARAMETER("out of range")   
 

可是我明明 #define _SECURE_SCL_THROWS 1 了啊。过一段时间有机会再查吧。

0 0
原创粉丝点击