Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c_str的奇怪行为?_C++ - Fatal编程技术网

C++ c_str的奇怪行为?

C++ c_str的奇怪行为?,c++,C++,我有一个下面的代码片段。我希望输出将是mystring,但奇怪的是它会输出垃圾字符 #include <iostream> #include <string> using namespace std; int main(int argc, char *argv[]) { string s1("mystring"); const char* s2 = s1.c_str(); s1 = "Hi there, this is a changed

我有一个下面的代码片段。我希望输出将是
mystring
,但奇怪的是它会输出垃圾字符

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char *argv[]) {
    string s1("mystring");

    const char* s2 = s1.c_str();

    s1 = "Hi there, this is a changed string s1";

    cout << s2 << endl;

    return 0;
}
#包括
#包括
使用名称空间std;
int main(int argc,char*argv[]){
字符串s1(“mystring”);
const char*s2=s1.c_str();
s1=“您好,这是一个已更改的字符串s1”;
cout
s1.c_str()
不返回独立于
s1
的内存。更改
s1
将使
s1.c_str()返回的指针无效

换句话说,要小心使用<代码> CySTR 。一般来说,它将C字符串传递给不接受C++字符串的函数。

< P>:

c_str()
获取的指针可能因以下原因而无效:

  • 对字符串调用非常量成员函数,不包括运算符[]、at()、front()、back()、begin()、rbegin()、end()和 rend()
通过修改字符串,您不再具有有效的指针


此外,您的前提是错误的。没有分配/释放内存。w.r.t.
c_str
c_str
data
(两者在c++11中相同)返回指向基础存储的指针。它不拥有存储。无论出于何种原因更改存储时,指针不再有效(即,它现在可能指向垃圾).

s2
不拥有该字符串。UB随后出现。但奇怪的是,它会输出垃圾字符。--我看不出这有什么奇怪的。这与抓住指向动态分配内存的指针没有什么不同,内存会被释放,如果您试图使用释放的指针,谁知道您将指向什么。std::string通常需要重新分配内存来存储字符串内容。它并不总是倾向于对非常短的字符串进行微优化。但您有很好的证据表明正在进行重新分配,s2现在是一个悬空指针。您也有很好的证据表明,您使用了一个堆分配器,该分配器故意清除已删除的堆blocks,这是帮助诊断悬空指针错误的常用方法。@PaulMcKenzie在我的日常工作中,我每次都会处理我的软件的奇怪行为,直到我发现它与我写的完全一样(但不是我想要实现的)。因此,我不会判断“奇怪”这个词太难了…;-)快速提及OP,作为一个新用户,花时间为我们提供了一个新的任务,解释了他们观察到的和预期的行为,解释了他们的想法,并向我们提出了一个具体的问题。我很高兴看到更多这样的问题。但是,在s1的新任务之前调用了c_str,那么s2的旧任务是如何更改的?@OnkarNMahajan这没有什么区别。可能发生的情况是cstr返回一个指向s1使用的内部内存的指针。当s1分配给该内存时,指针被释放,因此指针变得无效。但是在新分配给s1之前调用了c_str,那么如何更改对s2的旧分配?@OnkarNMahajan
s2
只是一个指针(指向
s1
的内容)。如果
s1
被修改(例如通过赋值)
s2
将无效。这可能意味着“一切都没有”。例如
s2
仍然指向
s1
的内容(现在已修改)。或者:
s2
指向已释放的内存。(它被称为“野生”指针)分配
s1
意味着你不能使用
s2
。这并不意味着你不能使用,但这样做被认为是错误的。