To elaborate on what Duoas is saying, substr returns a string. This string is a temporary object that is destroyed as soon as it is no longer being used (at the end of the line)
So at the end of the line, since the temporary string is destroyed, your 'cstr' pointer is left pointing to string data that no longer exists (bad pointer).
Ah, thanks. It's pretty obvious once you think about it, but it hadn't occurred to me that c_str() would return data that is "bound" to the string itself.