[英]Why does cout << *s << endl produce a segfault?
我在C ++类的实践考试中有这个问题,我们应该写输出是什么,或者它是否产生错误。 运行此代码会产生分段错误,但有人可以解释原因吗? 对我来说很好。
string *s;
s = (string *) "This is my house. I have to defend it.";
cout << *s << endl;
当未指向std::string
类型的对象时,通过类型为std::string*
的指针进行间接具有未定义的行为。
字符串文字不是std::string
类型的对象。 字符串文字是字符数组。 std::string
是在标题<string>
定义的类。
运行此代码会产生分段错误,但有人可以解释原因吗?
您通过不指向兼容类型对象的指针进行间接访问。 您的程序的行为是不确定的。
PS永远不需要使用C样式转换(例如(type)expression
)。 它可以轻松地抑制有用的编译错误并将其替换为未定义的行为。 应该避免。
如果您在这里没有使用C风格的转换,那么类型系统会在开始运行该程序之前警告您该错误。 在这种情况下,您可能会看到类似于以下内容的错误消息:
error: cannot convert 'const char [39]' to 'std::string*' {aka 'std::basic_string<char>*'} in assignment
帮助您意识到类型不匹配。
您需要了解字符串文字和类std::string
之间的区别。
将字符串文字转换为std::string*
是未定义的行为。 当代码执行*s
由于s
无效,这在这里表现为分段错误。
如果没有C样式转换(string *)
在s = (string *) "T...";
编译器将发出错误。
始终对C ++中的C样式转换提出疑问。
可能的问题(或至少一个问题)是s没有分配内存的事实。 您需要使用new关键字,然后尝试执行以下操作:
string *s;
s = new string("This is my house. I have to defend it.");
cout << *s << endl;
当然,理论上您也需要使用delete。
std :: string倾向于归结为以下形式:
struct string
{
char* _begin;
char* _end;
char* _capacity;
};
您定义的文本字符串如下所示:
const char* const text = "This is my house. I have to defend it."
因此,您正在从类型(char *)转换为类型(string *)。 现在,这意味着_begin将存储位置“ This is” ,而_end将存储位置“ my house”
当将字符串打印到std :: cout时,它将取消引用s的指针,并尝试查找字符串大小,通常这样实现:
size_t string::size() const { return _end - _begin; }
鉴于_begin和_end不存储指针值(它们只是文本的随机位),这将导致cout尝试打印非常错误数量的字符_(因为_begin和end中的存储位置是无意义的)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.