ITERATOR LIST CORRUPTED in std::string constructor - c++

The code below compiled in Debug configuration in VS2005 SP1 shows two messages with “ITERATOR LIST CORRUPTED” notice.
Code Snippet
#define _SECURE_SCL 0
#define _HAS_ITERATOR_DEBUGGING 0
#include <sstream>
#include <string>
int main()
{
std::stringstream stream;
stream << "123" << std::endl;
std::string str = stream.str();
std::string::const_iterator itFirst = str.begin();
int position = str.find('2');
std::string::const_iterator itSecond = itFirst + position;
std::string tempStr(itFirst,itSecond); ///< errors are here
return 0;
}
Is it a bug in the compiler or standard library?

My bad! Edit: Yeah problem with compiler. See this -- particularly the Community Content section.

What #dirkgently said in his edit.
Apparently, some code for std::string is located in the runtime dll, in particular the macro definition does not take effect for the constructor an the code for iterator debugging gets executed. You can fix this by linking the runtime library statically.
I would consider this a bug, though perhaps not in the Visual Studio itself, but in the documentation.

There is a problem with your code. Well, several in fact:
std.find('2') returns a size_t, you have a potential cast problem if the value of the size_t returned (like std::string::npos) is superior to what an int can hold (you would end up with a negative int I think...)
if position is negative, or equal to std::string::npos then the range itFirst,itSecond is ill-defined (either because itSecond is before itFirst or because it is past str.end())
Correct your code, and check if it stills throw. Iterator Debugging is here to help you catch these mistakes, disabling it acting like an ostrich.

Related

Garbage value in implicit conversion from expression `wchar_t + wchar_t[]` to std::wstring

I have come across something weird in Visual Studio C++ 2013 Community Edition which is either a compiler bug or I'm writing invalid code that does compile without warnings.
Consider the following snippet:
#include <string>
#include <iostream>
int main()
{
std::wstring text;
wchar_t firstChar = 'A';
text = firstChar + L"B";
std::wcout << text << std::endl;
return 0;
}
I expect the output to be "AB" but what I get is random garbage.
My question: is the operator+ between the wchar_t and wchar_t[] ill-defined, or is this a compiler/library bug?
In the case that it is ill-defined, should the compiler have issued a warning?
Note: I am not looking for a solution/workaround. Changing L"B" to std::wstring(L"B") fixes the problem. What I want to know is if I did something wrong or if the compiler did.
Note 2: I also get a garbage result in Visual Studio C++ 2010 and an online compiler which supposedly uses g++, and no compilation error, so I'm leaning towards that code being invalid, even though I would expect a compiler error.
firstChar + L"B" increments the address of the string literal L"B" with the promoted value of firstChar. It doesn't concatenate the character and the string. This is undefined behavior since std::basic_string will try to copy the string until it finds L'\0', which is beyond its original bound.
std::basic_string has multiple overloaded operators that allow operations like this to have intuitive behavior, which is why it works in that case.

Varying case-insensitive string comparisons performance

So, my phd project relies on a piece of software I've been building for nearly 3 years. It runs, its stable (It doesn't crash or throw exceptions) and I'm playing with the release version of it. And I've come to realise that there is a huge performance hit, because I'm relying too much on boost::iequals.
I know, there's a lot of on SO about this, this is not a question on how to do it, but rather why is this happening.
Consider the following:
#include <string.h>
#include <string>
#include <boost/algorithm/string.hpp>
void posix_str ( )
{
std::string s1 = "Alexander";
std::string s2 = "Pericles";
std::cout << "POSIX strcasecmp: " << strcasecmp( s1.c_str(), s2.c_str() ) << std::endl;
}
void boost_str ( )
{
std::string s1 = "Alexander";
std::string s2 = "Pericles";
std::cout << "boost::iequals: " << boost::iequals( s1, s2 ) << std::endl;
}
int main ( )
{
posix_str();
boost_str();
return 0;
}
I put this through valgrind and cachegrind, and to my suprise, boost is 4 times slower than the native posix or the std (which appears to be using the same posix) methods. Four times, now that is a lot, even considering that C++ offers a nice safety net. Why is that? I would really like other people to run this, and explain to me, what makes such a performance hit. Is it all the allocations (seems to be from the caller map).
I'm not dissing on boost, I love it and use it everywhere and anywhere.
EDIT: This graph shows what I mean
Boost::iequals is locale-aware. As you can see from its definition here it takes an optional third parameter that is defaulted to a default-constructed std::locale, that represents the current global C++ locale, as set by std::locale::global.
This more or less means that the compiler has no way to know in advance which locale is going to be used, and that means that there will be an indirect call to a certain function to convert each character to lower-case in the current locale.
On the other hand, the documentation for strcasecmp states that:
In the POSIX locale, strcasecmp() and strncasecmp() shall behave as if the strings had been converted to lowercase and then a byte comparison performed. The results are unspecified in other locales.
That means that the locale is fixed, hence you can expect it to be heavily optimized.

Bug of compiler or boost library?

This program (it has been narrowed down from a larger program) always crashes after compiled in vs2008 Release(Win32) mode under windows 7. I am not familiar with assembly code and don't know it's a bug of compiler or boost::ends_with or boost::asio::buffers_iterator. It can be compiled and executed with g++ in Ubuntu without any problem.
People said it's very unlikely to be compiler's bug, but when compiled in debug moded(or disable optimization), the problem does disappear.
I have been stuck with this problem for quite a few hours. Any help is appreciated. Thanks in advance.
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/algorithm/string.hpp>
typedef boost::asio::buffers_iterator<boost::asio::const_buffers_1> iterator_t;
typedef boost::iterator_range<iterator_t> range_t;
static const std::string LINE_END_MARK = "\r\n";
int main(int argc, char* argv[])
{
boost::asio::streambuf _buf;
std::ostream os(&_buf);
os<<"END\r\n";
iterator_t cursor = boost::asio::buffers_begin(_buf.data());
iterator_t end = boost::asio::buffers_end(_buf.data());
std::ostream_iterator<char> it(std::cout," ");
std::copy(LINE_END_MARK.begin(), LINE_END_MARK.end(), it);
range_t r(cursor, end);
if(!boost::ends_with(r, LINE_END_MARK))
return 0;
return 1;
}
Edit: I misread the code, sorry.
Your cursor and end iterators are pointing to invalid memory. You modified the underlying streambuf which reallocated during the copy to the output iterator. asio streambuf lets you access the raw memory for performance reasons, but the caveat is you have to worry about things like this.
Debug and release will change the way allocation and deallocation behave with regards to the underlying size of the allocated block and how memory may be fenced, guarded, initialized, aligned, etc.
Construct your iterators after the copy operation to fix your problem.
It doesn't work because 'range_t r(cursor, end)' is a range of "buffers" not a range of characters. So you are comparing a list of buffer pointers with each character in LINE_END_MARK.
If crashes in release mode under win32 because in windows you end up de-referencing a null pointer causing the crash.
boost asio has this concept of multiple buffers, but currently it's not really used. If you look at the implementation if only really uses 'const_buffers_1' or 'mutable_buffers_1' which is basically a list of 1 buffer.
I assume you want to compare the contents of the buffer, not a list of buffers range.
So you want to do something like:
typedef boost::iterator_range<const char*> range_t;
range_t r(boost::asio::buffer_cast<const char*>(_buf.data()), boost::asio::buffer_cast<const char*>(_buf.data()) + boost::asio::buffer_size(_buf.data()));
if(!boost::ends_with(r, LINE_END_MARK))
return 0;
return 1;

equivalent of atoi

Is there a function that could replace atoi in c++.
I made some research and didn't find anything to replace it, the only solutions would be using cstdlib or implementing it myself
If you don't want to use Boost, C++11 added std::stoi for strings. Similar methods exist for all types.
std::string s = "123"
int num = std::stoi(s);
Unlike atoi, if no conversion can be made, an invalid_argument exception is thrown. Also, if the value is out of range for an int, an out_of_range exception is thrown.
boost::lexical_cast is your friend
#include <string>
#include <boost/lexical_cast.hpp>
int main()
{
std::string s = "123";
try
{
int i = boost::lexical_cast<int>(s); //i == 123
}
catch(const boost::bad_lexical_cast&)
{
//incorrect format
}
}
You can use the Boost function boost::lexical_cast<> as follows:
char* numericString = "911";
int num = boost::lexical_cast<int>( numericString );
More information can be found here (latest Boost version 1.47). Remember to handle exceptions appropriately.
Without boost:
stringstream ss(my_string_with_a_number); int my_res; ss >> my_res;
About as annoying as the boost version but without the added dependency. Could possibly waste more ram.
You don't say why atoi is unsuitable so I am going to guess it has something to do with performance. Anyway, clarification would be helpful.
Using Boost Spirit.Qi is about an order of magnitude faster than atoi, at least in tests done by Alex Ott.
I don't have a reference but the last time I tested it, Boost lexical_cast was about an order of magnitude slower than atoi. I think the reason is that it constructs a stringstream, which is quite expensive.
Update: Some more recent tests

Tuple templates in GCC

I first started C++ with Microsoft VC++ in VS2010. I recently found some work, but I've been using RHEL 5 with GCC. My code is mostly native C++, but I've noticed one thing...
GCC doesn't appear to recognize the <tuple> header file, or the tuple template. At first I thought maybe it's just a typo, until I looked at cplusplus.com and found that the header is indeed not part of the standard library.
The problem is that I like to write my code in Visual Studio because the environment is way superior and aesthetically pleasing than eclipse or netbeans, and debugging is a breeze. The thing is, I've already written a good chunk of code to use tuples and I really like my code. How am I supposed to deal with this issue?
Here's my code:
using std::cout;
using std::make_tuple;
using std::remove;
using std::string;
using std::stringstream;
using std::tolower;
using std::tuple;
using std::vector;
// Define three conditions to code
enum {DONE, OK, EMPTY_LINE};
// Tuple containing a condition and a string vector
typedef tuple<int,vector<string>> Code;
// Passed an alias to a string
// Parses the line passed to it
Code ReadAndParse(string& line)
{
/***********************************************/
/****************REMOVE COMMENTS****************/
/***********************************************/
// Sentinel to flag down position of first
// semicolon and the index position itself
bool found = false;
size_t semicolonIndex = -1;
// Convert the line to lowercase
for(int i = 0; i < line.length(); i++)
{
line[i] = tolower(line[i]);
// Find first semicolon
if(line[i] == ';' && !found)
{
semicolonIndex = i;
// Throw the flag
found = true;
}
}
// Erase anything to and from semicolon to ignore comments
if(found != false)
line.erase(semicolonIndex);
/***********************************************/
/*****TEST AND SEE IF THERE'S ANYTHING LEFT*****/
/***********************************************/
// To snatch and store words
Code code;
string token;
stringstream ss(line);
vector<string> words;
// A flag do indicate if we have anything
bool emptyLine = true;
// While the string stream is passing anything
while(ss >> token)
{
// If we hit this point, we did find a word
emptyLine = false;
// Push it onto the words vector
words.push_back(token);
}
// If all we got was nothing, it's an empty line
if(emptyLine)
{
code = make_tuple(EMPTY_LINE, words);
return code;
}
// At this point it should be fine
code = make_tuple(OK, words);
return code;
}
Is there anyway to save my code from compiler incompatibility?
As long as it's just a pair you can use
typedef pair<int,vector<string>> Code;
But I don't think tuple is standard C++ (turns out it is included in TR1 and consequently also standard C++0x). As usual Boost has you covered though. So including:
#include "boost/tuple/tuple.hpp"
will solve your problem across compilers.
Compilers that ship the TR1 library should have it here
#include <tr1/tuple.hpp>
//...
std::tr1::tuple<int, int> mytuple;
Of course for portability you can use the boost library version in the meantime