所以我试图连接简单的字符串,并做出最后一句话。
int main()
{
string I ("I");
string Love ("Love");
string STL ("STL,");
string Str ("String.");
string fullSentence = '\0';
// Concatenate
fullSentence = I + " " + Love + " " + STL + " " + Str;
cout << fullSentence;
return 0;
}
在这里,我不想没有任何内容的“ fullSentence”,所以我分配了null,这给了我一个错误。除了以下我完全不理解的错误消息外,没有任何错误消息:
在exercise_4.exe中的0x51C3F6E0(ucrtbased.dll)处引发的异常:0xC0000005:访问冲突读取位置0x00000000。发生
我删除“ \ 0”后,它就可以正常工作。为什么会这样?
答案 0 :(得分:3)
对我来说,这似乎是MSVC编译器的错误。
声明:
string fullSentence = '\0';
不应该编译。
实际上,从char
(即'\0'
)到std::string
没有有效的(隐式)构造函数。 Reference Here。
请注意,gcc和clang不接受此代码为有效代码。 MSVC可以。
为什么会这样?
查看汇编代码,MSVC使用以下构造函数编译该语句:
std::string::string(char const * const);
将'\0'
作为参数传递,它将实际上转换为nullptr
。
所以:
使用内容以s指向的以空终止的字符串的副本初始化的内容来构造字符串。字符串的长度由第一个空字符确定。如果[s,s + Traits :: length(s))不是有效范围(例如,,如果s是空指针),则该行为是不确定的。
所以您的代码是未定义的行为。
答案 1 :(得分:1)
放入"\0"
而不是'\0'
。在C ++中,''
用于字符,""
用于字符串。
这是从char
到非标量类型std::string
答案 2 :(得分:1)
您可以使用调试器查看发生了什么的调用堆栈。 调查字符串类here 在您的情况下调用了以下构造函数:
basic_string( const CharT* s, const Allocator& alloc = Allocator() );
按照构造函数的描述(重点是我的)构造 字符串,其内容用 s指向以null结尾的字符串。的长度 字符串由第一个空字符确定。 行为是 如果[s,s + Traits :: length(s))不是有效范围,则未定义
在您的情况下,范围为空->无效。