【问题标题】:Accidentally linking c_str() strings意外链接 c_str() 字符串
【发布时间】:2021-12-27 23:49:05
【问题描述】:

我正在尝试将一个字符串分配给一个结构值,这可行,但该值以某种方式链接到变量:

string tmp;
struct test_struct{
    const char *server, *user; 
};
test_struct test;

tmp = "foo";
test.server = tmp.c_str();
cout << test.server << endl;

tmp = "bar";
test.user = tmp.c_str();
cout << test.user << endl;

cout << "" << endl;

cout << test.server << endl;
cout << test.user << endl;

输出是:

foo
bar

bar
bar

谁能解释一下为什么会这样?

【问题讨论】:

  • 问问自己——这些指针指向内存的哪个位置?这些指针的有效期是多久?使用原始指针意味着跟踪所指向数据的所有权和跟踪生命周期。更简单的方法是使用 std::string 而不是原始指针。
  • 请注意,在执行tmp = "bar"; 之后访问test.server 会导致未定义的行为。只要您调用字符串的非常量成员函数,std::string::c_str 返回的指针就会失效(有一些例外)。其中包括operator=
  • serveruser 存储tmp 中任何字符序列的地址。如果您更改tmp 的内容,可能会发生两种情况:1) 新值写入相同的内存位置,或 2) 新值写入新的内存位置。如果在更改tmp 之后,您从serveruser 读取,它们仍然指向原始地址,则可能会发生两件事:A)您读取了新值,或者B)您基本上可以读取任何内容。但由于 1 和 2 是您无法控制的实现细节,因此您应该只考虑您的代码会产生 B 行为。

标签: c++ string c-str


【解决方案1】:
struct test_struct{
    const char *server, *user; 
};
test_struct test;

好的,所以test.server 是一个指针。

test.server = tmp.c_str(); // 1
cout << test.server << endl; // 2

tmp = "bar"; // 3
test.user = tmp.c_str();
cout << test.user << endl;

cout << "" << endl;

cout << test.server << endl; // 4

在 1 中,您将 test.server 设置为指向 tmp 的内容。在2中,你输出test.server指向的东西,这很好。

在3中,修改tmp的内容。所以现在,test.server 指向了一些不再存在的东西——tmp 以前的内容。

在 4 中,您输出 test.server 指向的内容。但那是 tmp 回到 1 的内容,你在 3 中销毁了。

你不能输出你删除的东西。

【讨论】:

  • 嗯,显然你可以,但你没有得到你希望的结果
猜你喜欢
  • 2013-10-14
  • 1970-01-01
  • 2022-10-25
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2019-08-02
相关资源
最近更新 更多