函数终止后的C++字符串文字更改



我有三个类似的函数:

MyStruct foo() {
//do something...
return get_var("string literal");
}
MyStruct get_var(const string &literal) {
return (MyStruct) {some_attribute, &*literal.begin(), literal.size()}; //struct needs const char*
}
void bar() {
Mystruct var;
//do stuff
var = foo();
std::cout << var.string_attribute;
}

这应该打印";字符串文字";,但是,字符串的前半部分是一堆随机的字符。如果我这样做:

MyStruct get_var(const string &literal) {
std::cout << literal;
return (MyStruct) {some_attribute, &*literal.begin(), literal.size()}; //struct needs const char*
}

只有第一次打印正确。如果我这样做:

MyStruct foo() {
//do something...
string my_literal = "string literal";
std::cout << my_literal;
return get_var(my_literal);
}

第一次和第二次打印正确,但第三次打印不正确。我不知道发生了什么;我认为字符串文字会永远存在,所以它不应该被覆盖或其他任何东西。非常感谢您的帮助。

c++是一种从c中发展出来的古老语言,其结果是,用于描述该行为的行为和术语都可能相当混乱。

A";字符串文字";是源代码中用引号括起来的一系列字符。在大多数上下文中,它的计算结果是指向以null结尾的字符序列("C字符串"(的指针。在正常情况下,*所述字符序列在整个进程的生命周期内确实有效。

另一方面,代码中的类型string可能指的是std::string(通过某个地方的using namespace std(,它是一个表示自动管理字符串的类

当进行CCD_ 4或CCD_;C字符串";被隐式地转换为CCD_ 6。此操作将创建字符序列的副本。与原始字符序列不同,当拥有该字符序列的std::string被销毁时,该字符序列将被释放。

&literatl.begin是一种有点非正统的方法,可以获得指向std::字符串所拥有的字符序列的指针。使用c_str会更正常。不过,这与你的问题无关。重要的一点是,内存中的字符序列是由std::字符串拥有的,而不是字符串文字中的原始序列。

get_var("string literal");的情况下,一旦语句完成,std::字符串就会被销毁。在string my_literal = "string literal";的情况下,当变量my_literal超出范围时,它被销毁。无论哪种方式,它都会在foo()返回之前被销毁。因此,当您执行std::cout << var.string_attribute;时,您引用的是一个过时的指针,该指针的相关内存已经被释放。

它工作的原因";有时";内存管理器通常不会在内存释放后立即覆盖内存。通常情况下,在某些东西重新使用内存之前,内存实际上不会被覆盖。

编辑:误读了你的问题。可以在免费使用后使用;工作;有时,但这里不是这样。您说正在工作的cout调用位于代码中std::字符串仍然有效的位置。

*排除在运行时卸载共享库等超出C标准范围的情况。

启用最大编译器警告。它应该提醒您,您正试图返回指向临时对象的指针。

string my_literal = "string literal";创建一个字符串,然后将对该字符串的常量引用传递到函数中。则在foo()结束时,my_literal销毁。它是消失。任何指向它的指针现在都是无效的。

在那之后,任何不好的事情都可能发生,这是未定义的行为。

最新更新