c++ - 不同的字符串变量指向相同的地址

标签 c++ string stl

当我遇到奇怪的字符串转换时,我发现不同的字符串变量指向同一个地址。

我在示例中制作了 3 个字符串变量。我认为 a 和 b 应该指向相同的地址,因为 b 是 a 的引用变量。

但变量 c 也指向与 a 和 b 相同的地址。我不明白这个...

如果您能给我任何建议,我将不胜感激。


问题:

  1. 为什么a、b、c变量指向同一个地址?

  2. 改变“c[2]”值后,c 指向不同的地址。你能解释一下吗?

  3. 两种方法有什么区别?

c[2] = 'z';

// Variable c changed value, but address is still same.

char temp = (char)c.c_str(); temp[2] = 'z';


编译器版本: g++ (GCC) 4.4.7 20120313 (红帽 4.4.7-11)

编译选项: g++ -o 测试测试.c

这是我的代码。

#include <iostream>
#include <string.h>
#include <stdio.h>

void print(std::string var_name, const std::string &s)
{
    const char *ps = s.c_str();
    printf("[%s] value=%s, address=%p\n", var_name.c_str(), s.c_str(), ps);
}

int main()
{
    std::string a = "ab;cd;ef;gh";
    const std::string &b = a;
    std::string c;
    c = b;

    print("a", a);
    print("b", b);
    print("c", c);

    c[2] = 'z';
    //char *temp = (char*)c.c_str();
    //temp[2] = 'z';

    print("a", a);
    print("b", b);
    print("c", c);
#if 0
    std::cout << "a=" << a << std::endl;
    std::cout << "b=" << b << std::endl;
    std::cout << "c=" << c << std::endl;

    //c[0] = 'z';

    std::cout << "after change";

    char *temp = (char*)c.c_str();
    temp[2] = '1';

    std::cout << "a=" << a << std::endl;
    std::cout << "b=" << b << std::endl;
    std::cout << "c=" << c << std::endl;
#endif
    return 0;
}

结果:

[a] 值=ab;cd;ef;gh, 地址=0x705028

[b] 值=ab;cd;ef;gh,地址=0x705028

[c] 值=ab;cd;ef;gh,地址=0x705028

[a] 值=ab;cd;ef;gh, 地址=0x705028

[b] 值=ab;cd;ef;gh,地址=0x705028

[c] 值=abzcd;ef;gh,地址=0x705058

最佳答案

首先,您必须了解引用。引用基本上是其他事物的别名。一旦将 b 初始化为对 a 的引用,b 实际上就是 a 的别名,并且当您使用b 编译器(以某种方式)将其转换为 a

至于为什么地址相同,可能只是编译器和标准库的优化。 ac 都被初始化为相同的内容,为什么不共享这些内容呢?节省内存。当一个字符串被修改时,它将字符串复制到它自己的内存中。


至于您对 temp 的使用,这是非常错误的,并且会导致未定义的行为。来自 this c_str reference :

Writing to the character array accessed through c_str() is undefined behavior.

c_str 中的c 代表常量(即只读)。您需要使用 C 风格的转换表明您正在做一些可能很危险而且通常很糟糕的事情。

关于c++ - 不同的字符串变量指向相同的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34783654/

相关文章:

c++ - split_interval_map用法,高效找到所有与一个点相交的区间

c++ - 包括 boost function.hpp,但不使用它,会使我的二进制文件的大小增加 200k。为什么?

c++ - 为什么在没有明显代码的情况下删除对象?

java - android studio 3.0更新或错误代码引起的问题?

sql - PostgreSQL - 使用大小写将带引号的字符串转换为不同的字符串?

c++ - 将 cin 用于 char 数组

java - 在 Java 中构造 HTML 字符串的简单/直接/Heredoc 方式

c++ - 替换C++字符串中的标点符号

c++ - unordered_set 非 const 迭代器

c++ - c++11 中是否有 Boost.Bimap 替代方案?