What is invalid parameter noinfo and how do I get rid of it分(如何优化stl迭代器)
来源:互联网 发布:电机调速的c编程 编辑:程序博客网 时间:2024/06/01 11:59
What is invalid parameter noinfo and how do I get rid of it?
_invalid_parameter_noinfo shows up as a problem most often as an “Unresolved external symbol” when you get some mix up between DEBUG and RELEASE modes. But it’s also a performance problem in situations where it’s compiled in unnecessarily.
So what is it? Well, it’s basically the function that gets called when the Microsoft Visual C++ compiled code detects a type of run-time error, such as a vector index out of range, or incrementing an iterator past the end of a container.
There are two functions: _invalid_parameter, which gets called in debug mode, and _invalid_parameter_noinfo, which gets called in non-debug mode. If you have a module compiled without _DEBUG defined, and you link with the debug library, then you will get the “Unresolved external symbol” error. This could be a problem with inconsistent #includes. See this thread on devmaster.net for some practical experiences.
What is _invalid_parameter_noinfo then? Well, first ask what _invalid_parameter is. _invalid_parameter is basically an assert. When an error is detected, _invalid_parameter is called, and is passed debug information, like the file name and line number pointers. It then calls _crt_debugger_hook and _invoke_watson. In non-debug mode (release mode), the debug info is not available, so invalid_parameter_noinfo simply calls invalid_parameter with NULL parameters. It’s actually an optimization, saving having the NULL parameters passed from every bit of your code, instead you code “just” needs to call this one function
You might also be having problems with _invalid_parameter_noinfo if you have code that crashes (on this function) on in release mode. That’s most likely some form of release-only bug, such as uninitialized memory, and the call to _invalid_parameter_noinfo is the end result. DO NOT IGNORE IT, or try to work around it. You need to find out exactly why it is being called.
But suppose your code works fine, and _invalid_parameter_noinfo is never called, you might be peeking through the disassembly, trying to figure out why it is so slow, and you see all these calls to _invalid_parameter_noinfo
Consider this code:
voidCVerletPoint::SatisfyConstraints(){vector::iterator i;for (i = mp_constraints.begin(); i != mp_constraints.end(); i++){(*i)->Satisfy(this);}}
A nice simple bit of code that just iterates over a vector of CVerletConstraint objects, and calls some function on each one. It compiles to this:
00405C20 push ebx 00405C21 push ebp 00405C22 push esi 00405C23 mov ebp,ecx 00405C25 mov esi,dword ptr [ebp+20h] 00405C28 cmp esi,dword ptr [ebp+24h] 00405C2B push edi 00405C2C lea edi,[ebp+1Ch] 00405C2F jbe CVerletPoint::SatisfyConstraints+16h (405C36h) 00405C31 call _invalid_parameter_noinfo (407A81h) 00405C36 mov ebx,dword ptr [edi+8] 00405C39 cmp dword ptr [edi+4],ebx 00405C3C jbe CVerletPoint::SatisfyConstraints+23h (405C43h) 00405C3E call _invalid_parameter_noinfo (407A81h) 00405C43 test edi,edi 00405C45 je CVerletPoint::SatisfyConstraints+2Bh (405C4Bh) 00405C47 cmp edi,edi 00405C49 je CVerletPoint::SatisfyConstraints+30h (405C50h) 00405C4B call _invalid_parameter_noinfo (407A81h) 00405C50 cmp esi,ebx 00405C52 je CVerletPoint::SatisfyConstraints+5Fh (405C7Fh) 00405C54 test edi,edi 00405C56 jne CVerletPoint::SatisfyConstraints+3Dh (405C5Dh) 00405C58 call _invalid_parameter_noinfo (407A81h) 00405C5D cmp esi,dword ptr [edi+8] 00405C60 jb CVerletPoint::SatisfyConstraints+47h (405C67h) 00405C62 call _invalid_parameter_noinfo (407A81h) 00405C67 mov ecx,dword ptr [esi] 00405C69 mov eax,dword ptr [ecx] 00405C6B mov edx,dword ptr [eax] 00405C6D push ebp 00405C6E call edx 00405C70 cmp esi,dword ptr [edi+8] 00405C73 jb CVerletPoint::SatisfyConstraints+5Ah (405C7Ah) 00405C75 call _invalid_parameter_noinfo (407A81h) 00405C7A add esi,4 00405C7D jmp CVerletPoint::SatisfyConstraints+16h (405C36h) 00405C7F pop edi 00405C80 pop esi 00405C81 pop ebp 00405C82 pop ebx 00405C83 ret
Yikes! What exactly is going on there? Lots of run time error checking, that’s what. Why is it doing this? Well, it’s to make your code “secure”, it makes it so that if something goes out of bounds, then the program will halt, preventing it from doing any harm (or being exploited by a hacker), and allowing you to debug it.
Is this a good thing? It depend on what you want. If you are writing code with lots of convoluted data structures and container interactions, then maybe this is something you want. But for code that operates on a data structure that does not change from frame to frame, then this code is just getting in the way. If it works the first frame, it will work forever. In release mode I do not expect this kind of error checking, and it certainly look like it would hurt performance. It is tests that always return true, skipping over a function that is never called.
So, you can turn it off with:
#ifndef _DEBUG#define _SECURE_SCL 0#endif
You will need that either defined in every file, or have _SECURE_SCL defined as 0 in the release build process.
Effect: Our code from above now shrinks to:
00405AF0 push esi 00405AF1 push edi 00405AF2 mov edi,ecx 00405AF4 mov esi,dword ptr [edi+20h] 00405AF7 cmp esi,dword ptr [edi+24h] 00405AFA je CVerletPoint::SatisfyConstraints+21h (405B11h) 00405AFC lea esp,[esp] 00405B00 mov ecx,dword ptr [esi] 00405B02 mov eax,dword ptr [ecx] 00405B04 mov edx,dword ptr [eax] 00405B06 push edi 00405B07 call edx 00405B09 add esi,4 00405B0C cmp esi,dword ptr [edi+24h] 00405B0F jne CVerletPoint::SatisfyConstraints+10h (405B00h) 00405B11 pop edi 00405B12 pop esi 00405B13 ret
Much better. six tests have been eliminated. saving at least 12 lines of assembly code. And the big news, the framerate of my blob program goes from 150fps to 170fps.(优化后的效果)
Check here for an investigation of different ways of iterating over STL vectors:
http://einaros.blogspot.com/2007/02/iteration-techniques-put-on-benchmark.html
So, is turning off _SECURE_SCL a bad cowboy practice? Well for games I think it’s quite reasonable to switch it off for a “FINAL” build (i.e. the one you are going to release to the consumer). Leaving it on might be a useful debugging tool. Just be aware of the potential for significant performance degradation in instances like the one above. That kind of case might be ripe for some kind of refactoring with error checking that is only performed when the container changes.
_invalid_parameter_noinfo shows up as a problem most often as an “Unresolved external symbol” when you get some mix up between DEBUG and RELEASE modes. But it’s also a performance problem in situations where it’s compiled in unnecessarily.
So what is it? Well, it’s basically the function that gets called when the Microsoft Visual C++ compiled code detects a type of run-time error, such as a vector index out of range, or incrementing an iterator past the end of a container.
There are two functions: _invalid_parameter, which gets called in debug mode, and _invalid_parameter_noinfo, which gets called in non-debug mode. If you have a module compiled without _DEBUG defined, and you link with the debug library, then you will get the “Unresolved external symbol” error. This could be a problem with inconsistent #includes. See this thread on devmaster.net for some practical experiences.
What is _invalid_parameter_noinfo then? Well, first ask what _invalid_parameter is. _invalid_parameter is basically an assert. When an error is detected, _invalid_parameter is called, and is passed debug information, like the file name and line number pointers. It then calls _crt_debugger_hook and _invoke_watson. In non-debug mode (release mode), the debug info is not available, so invalid_parameter_noinfo simply calls invalid_parameter with NULL parameters. It’s actually an optimization, saving having the NULL parameters passed from every bit of your code, instead you code “just” needs to call this one function
You might also be having problems with _invalid_parameter_noinfo if you have code that crashes (on this function) on in release mode. That’s most likely some form of release-only bug, such as uninitialized memory, and the call to _invalid_parameter_noinfo is the end result. DO NOT IGNORE IT, or try to work around it. You need to find out exactly why it is being called.
But suppose your code works fine, and _invalid_parameter_noinfo is never called, you might be peeking through the disassembly, trying to figure out why it is so slow, and you see all these calls to _invalid_parameter_noinfo
Consider this code:
voidCVerletPoint::SatisfyConstraints(){vector::iterator i;for (i = mp_constraints.begin(); i != mp_constraints.end(); i++){(*i)->Satisfy(this);}}
A nice simple bit of code that just iterates over a vector of CVerletConstraint objects, and calls some function on each one. It compiles to this:
00405C20 push ebx 00405C21 push ebp 00405C22 push esi 00405C23 mov ebp,ecx 00405C25 mov esi,dword ptr [ebp+20h] 00405C28 cmp esi,dword ptr [ebp+24h] 00405C2B push edi 00405C2C lea edi,[ebp+1Ch] 00405C2F jbe CVerletPoint::SatisfyConstraints+16h (405C36h) 00405C31 call _invalid_parameter_noinfo (407A81h) 00405C36 mov ebx,dword ptr [edi+8] 00405C39 cmp dword ptr [edi+4],ebx 00405C3C jbe CVerletPoint::SatisfyConstraints+23h (405C43h) 00405C3E call _invalid_parameter_noinfo (407A81h) 00405C43 test edi,edi 00405C45 je CVerletPoint::SatisfyConstraints+2Bh (405C4Bh) 00405C47 cmp edi,edi 00405C49 je CVerletPoint::SatisfyConstraints+30h (405C50h) 00405C4B call _invalid_parameter_noinfo (407A81h) 00405C50 cmp esi,ebx 00405C52 je CVerletPoint::SatisfyConstraints+5Fh (405C7Fh) 00405C54 test edi,edi 00405C56 jne CVerletPoint::SatisfyConstraints+3Dh (405C5Dh) 00405C58 call _invalid_parameter_noinfo (407A81h) 00405C5D cmp esi,dword ptr [edi+8] 00405C60 jb CVerletPoint::SatisfyConstraints+47h (405C67h) 00405C62 call _invalid_parameter_noinfo (407A81h) 00405C67 mov ecx,dword ptr [esi] 00405C69 mov eax,dword ptr [ecx] 00405C6B mov edx,dword ptr [eax] 00405C6D push ebp 00405C6E call edx 00405C70 cmp esi,dword ptr [edi+8] 00405C73 jb CVerletPoint::SatisfyConstraints+5Ah (405C7Ah) 00405C75 call _invalid_parameter_noinfo (407A81h) 00405C7A add esi,4 00405C7D jmp CVerletPoint::SatisfyConstraints+16h (405C36h) 00405C7F pop edi 00405C80 pop esi 00405C81 pop ebp 00405C82 pop ebx 00405C83 ret
Yikes! What exactly is going on there? Lots of run time error checking, that’s what. Why is it doing this? Well, it’s to make your code “secure”, it makes it so that if something goes out of bounds, then the program will halt, preventing it from doing any harm (or being exploited by a hacker), and allowing you to debug it.
Is this a good thing? It depend on what you want. If you are writing code with lots of convoluted data structures and container interactions, then maybe this is something you want. But for code that operates on a data structure that does not change from frame to frame, then this code is just getting in the way. If it works the first frame, it will work forever. In release mode I do not expect this kind of error checking, and it certainly look like it would hurt performance. It is tests that always return true, skipping over a function that is never called.
So, you can turn it off with:
#ifndef _DEBUG#define _SECURE_SCL 0#endif
You will need that either defined in every file, or have _SECURE_SCL defined as 0 in the release build process.
Effect: Our code from above now shrinks to:
00405AF0 push esi 00405AF1 push edi 00405AF2 mov edi,ecx 00405AF4 mov esi,dword ptr [edi+20h] 00405AF7 cmp esi,dword ptr [edi+24h] 00405AFA je CVerletPoint::SatisfyConstraints+21h (405B11h) 00405AFC lea esp,[esp] 00405B00 mov ecx,dword ptr [esi] 00405B02 mov eax,dword ptr [ecx] 00405B04 mov edx,dword ptr [eax] 00405B06 push edi 00405B07 call edx 00405B09 add esi,4 00405B0C cmp esi,dword ptr [edi+24h] 00405B0F jne CVerletPoint::SatisfyConstraints+10h (405B00h) 00405B11 pop edi 00405B12 pop esi 00405B13 ret
Much better. six tests have been eliminated. saving at least 12 lines of assembly code. And the big news, the framerate of my blob program goes from 150fps to 170fps.(优化后的效果)
Check here for an investigation of different ways of iterating over STL vectors:
http://einaros.blogspot.com/2007/02/iteration-techniques-put-on-benchmark.html
So, is turning off _SECURE_SCL a bad cowboy practice? Well for games I think it’s quite reasonable to switch it off for a “FINAL” build (i.e. the one you are going to release to the consumer). Leaving it on might be a useful debugging tool. Just be aware of the potential for significant performance degradation in instances like the one above. That kind of case might be ripe for some kind of refactoring with error checking that is only performed when the container changes.
Checked Iterators
Checked iterators ensure that you do not overwrite the bounds of your container.
Checked iterators apply to release builds and debug builds. See Debug Iterator Support for more information on using iterators when compiling in debug mode.
For information on how to disable warnings generated by checked iterators, see _SCL_SECURE_NO_WARNINGS.
The following symbols are for use with the checked iterators feature.
- _SECURE_SCL
If defined as 1, unsafe iterator use causes a runtime error. If defined as 0, checked iterators are disabled. The exact behavior of the runtime error depends on the value of _SECURE_SCL_THROWS. The default value for _SECURE_SCL is 1, meaning checked iterators are enabled by default.
- _SECURE_SCL_THROWS
If defined as 1, an out of range iterator use causes an exception at runtime. If defined as 0, the program is terminated by calling invalid_parameter. The default value for _SECURE_SCL_THROWS is 0, meaning the program will be terminated by default. Requires _SECURE_SCL to also be defined.
When _SECURE_SCL=1 is defined:
All standard iterators (vector::iterator, for example) are checked.
The checked form of an algorithm will be used, for standard functions with checked forms (see list below).
If an output iterator is a checked iterator:
You will get checked behavior on calls to the standard function (std::copy, for example).
You will get checked behavior on calls to a checked function (stdext::checked_copy, for example).
You will get checked behavior on calls to an unchecked function (stdext::unchecked_copy, for example).
If the output iterator is an unchecked iterator (an array, for example):
Calls to the standard function (std::copy, for example) will result in compiler warnings.
Calls to the checked function (stdext::checked_copy, for example) will result in compiler warnings.
You will get unchecked behavior on calls to an unchecked function (stdext::unchecked_copy, for example).
The following functions will generate a runtime error if there is an access outside the bounds of the container:
basic_string::operator[]
bitset::operator[]
deque::back
deque::front
deque::operator[]
list::back
list::front
queue::back
queue::front
valarray::operator[]
vector::back
vector::front
vector::operator[]
When _SECURE_SCL=0 is defined:
All standard iterators are unchecked (iterators can move beyond the container boundaries, leading to undefined behavior).
The unchecked form of a function will be used, for standard functions with checked forms (see list below).
If an output iterator is a checked iterator:
You will get checked behavior on calls to the standard function (std::copy, for example).
You will get checked behavior on calls to a checked function (stdext::checked_copy, for example).
You will get checked behavior on calls to an unchecked function (stdext::unchecked_copy, for example).
If an output iterator is an unchecked iterator:
You will get unchecked behavior on calls to the standard function (std::copy, for example).
Calls to a checked function (stdext::checked_copy, for example) will result in compiler warnings.
You will get unchecked behavior on calls to an unchecked function (stdext::unchecked_copy, for example).
A checked iterator refers to an iterator that will throw an exception or call invalid_parameter if you attempt to move past the boundaries of the container. For more information about invalid_parameter, see Parameter Validation.
A checked algorithm enforces the use of a checked destination iterator. If passed an unchecked destination iterator, a checked algorithm will compile, but with warnings. See _SCL_SECURE_NO_WARNINGS for information on how to disable these warnings.
There are two iterator adaptors that support checked iterators:
checked_array_iterator Class
checked_iterator Class
The following algorithms enforce the use of a checked iterator as output iterator. This is useful when you want to compile with _SECURE_SCL=0, and where you identify some code where you want to enforce the use of checked iterators. The following algorithms are all defined in the stdext namespace.
The following algorithms are Microsoft extensions to the Standard C++ Library. Code implemented using these algorithms will not be portable.
checked_adjacent_difference
checked_copy
checked_copy_backward
checked_fill_n
checked_generate_n
checked_merge
checked_partial_sum
checked_remove_copy
checked_remove_copy_if
checked_replace_copy
checked_replace_copy_if
checked_reverse_copy
checked_rotate_copy
checked_set_difference
checked_set_intersection
checked_set_symmetric_difference
checked_set_union
checked_uninitialized_copy
checked_uninitialized_fill_n
checked_unique_copy
The following algorithms allow the use of an unchecked iterator as output iterator. This is useful when you want to compile with _SECURE_SCL=1, and where you want to selectively allow the use of unchecked iterators. The following algorithms are all defined in the stdext namespace.
The following algorithms are Microsoft extensions to the Standard C++ Library. Code implemented using these algorithms will not be portable.
unchecked_adjacent_difference
unchecked_copy
unchecked_copy_backward
unchecked_fill_n
unchecked_generate_n
unchecked_merge
unchecked_partial_sum
unchecked_remove_copy
unchecked_remove_copy_if
unchecked_replace_copy
unchecked_replace_copy_if
unchecked_reverse_copy
unchecked_rotate_copy
unchecked_set_difference
unchecked_set_intersection
unchecked_set_symmetric_difference
unchecked_set_union
unchecked_uninitialized_copy
unchecked_uninitialized_fill_n
unchecked_unique_copy
When compiling with _SECURE_SCL 1, a runtime error will occur if you attempt to access an element outside the bounds of the container with the indexing operator of certain classes (see above).
// checked_iterators_1.cpp// compile with: /EHsc#define _SECURE_SCL 1#define _SECURE_SCL_THROWS 1#include <vector>#include <iostream>using namespace std;int main() { vector<int> v; v.push_back(67); int i = v[0]; cout << i << endl; try { i = v[1]; } catch (std::out_of_range) { cout << "invalid container access" << endl; }};
Output
67invalid container access
When compiling with _SECURE_SCL 1, a runtime error will occur if you attempt to access an element with front or back of certain classes (see above), when the container is empty.
// checked_iterators_2.cpp// compile with: /EHsc#define _SECURE_SCL 1#define _SECURE_SCL_THROWS 1#include <vector>#include <iostream>int main() { using namespace std; vector <int> v1; try { int& i = v1.front(); } catch (std::out_of_range) { cout << "vector is empty!!" << endl; }}
Output
vector is empty!!
When compiling with _SECURE_SCL 1, the compiler enforces the use of a checked iterator on standard algorithms that also have checked and unchecked versions (see above).
// checked_iterators_3.cpp// compile with: /EHsc /W3#define _SECURE_SCL 1#include <algorithm>#include <iostream>using namespace std;using namespace stdext;int main() { int a[] = { 1, 2, 3 }; int *b = new int[10]; int c[10]; copy(a, a + 3, b); // C4996 unchecked iterator copy(a, a + 3, checked_array_iterator<int*>(c, _countof(c))); // OK delete[] b;}
The following example sets _SECURE_SCL to 0, thus disabling checked iterators. With checked iterators disabled, you must take extra caution to ensure you do not iterate beyond the bounds of your container.
// checked_iterators_4.cpp// compile with: /EHsc#define _SECURE_SCL 0#include <vector>#include <iostream>using namespace std;int main() { vector<int> v; v.push_back(67); int i = v[0]; cout << i << endl;};
Output
67
- What is invalid parameter noinfo and how do I get rid of it分(如何优化stl迭代器)
- What is invalid parameter noinfo and how do I get rid of it? (转)
- What is a cronjob and how do I use it?
- What is a NullPointerException, and how do I fix it?
- What is a "sosreport" and how do I create it in Red Hat Enterprise Linux 4.6 and later
- Hadoop: What it is, how it works, and what it can do
- What is overfitting and how can I avoid it?
- What is virtual memory, how is it implemented, and why do operating systems use it?
- Ground loop problems and how to get rid of them
- What Is UAT, And Why Do It?
- What is Logical Volume Management and How Do You Enable It in Ubuntu?
- what-is-the-bios-and-what-does-it-do
- What is DMA and what does it do?
- How do get rid of pustular dermatitis on 4 year ol
- How to get rid of threads
- How to get rid of EYE BAGS
- What is tethering and how do you enable tethering?
- Divitis: what it is, and how to cure it
- vc++6.0 编译时报错Fatal Error C1010 unexpected end of file while looking for precompiled header directive
- 【黑马程序员】Objective-C语言学习笔记之核心语法(四)
- C++变量的存储类别(动态存储、静态存储、自动变量、寄存器变量)
- 【Objective-C高级编程】iOS与OS X多线程和内存管理(二)
- 2014-03-19项目4-拓展二
- What is invalid parameter noinfo and how do I get rid of it分(如何优化stl迭代器)
- 图像处理程序,在状态栏显示图像尺寸
- nyoj-130 相同的雪花 (哈希)
- Web编程之一 urlparse
- 四周 项目4 扩展4 将项目四用多文件的方式组织起来 **第一百篇
- vc++6.0 编译时报错 LNK2001 on __beginthreadex and __endthreadex
- Ubuntu 12.04 安装使用dhcp server
- 一步步学习SPD2010--第十三章节--管理SP Server环境的Web内容(6)--允许用户给Web内容排名
- 在Mysql上创建数据表实例